home *** CD-ROM | disk | FTP | other *** search
- Subject: v25i002: lsof - a successor to fstat and ofiles
- Newsgroups: comp.sources.unix
- Approved: vixie@pa.dec.com
-
- Submitted-by: Victor A Abell <abe@mace.cc.purdue.edu>
- Posting-number: Volume 25, Issue 2
- Archive-name: lsof
-
- Lsof (for LiSt Open Files) lists files opened by processes on selected
- Unix systems. It is my answer to those who regularly ask me when I am
- going to make fstat (comp.sources.unix volume 18, number 107) or ofiles
- X(volume 18, number 57) available on SunOS 4.1.1 or the like.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: 00DIST 00README Makefile lsof.8 lsof.c sys sys/fss.h
- # Wrapped by vixie@cognition.pa.dec.com on Mon Dec 2 21:33:09 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f '00DIST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'00DIST'\"
- else
- echo shar: Extracting \"'00DIST'\" \(1564 characters\)
- sed "s/^X//" >'00DIST' <<'END_OF_FILE'
- X Notes for the comp.sources.unix distribution of lsof 1.0
- X
- Lsof (for LiSt Open Files) lists files opened by processes on selected
- Unix systems. It is my answer to those who regularly ask me when I am
- going to make fstat (comp.sources.unix volume 18, number 107) or ofiles
- X(volume 18, number 57) available on SunOS 4.1.1 or the like.
- X
- Lsof is a complete redesign of the fstat/ofiles series, based on the SunOS
- vnode model. Thus, it has been tested on AIX 3.1.[357], HP-UX [78].x,
- NeXTStep 2.[01], Sequent Dynix 3.0.12 and 3.1.2, and Sunos 4.1 and 4.1.1.
- Using available kernel access methods, such as nlist() and kvm_read(),
- lsof reads process table entries, user areas and file pointers to reach
- the underlying structures that describe files opened by processes.
- X
- Lsof interprets most vnode extensions -- cdrnodes, fifonodes, gnodes,
- inodes, rnodes, snodes and tmpnodes. It understands NFS connections. It
- recognizes FIFOs, multiplexed files, Unix and Internet sockets.
- X
- Lsof accepts options to limit and filter its output. That output describes
- the process that has opened the file, the command the process is executing,
- the owner of the process, the file descriptor of the file, and the file's
- device, inode number, size and file system name. Additional special output
- is provided for special files -- e. g., the local and destination Internet
- addresses of Internet socket files.
- X
- Lsof may be used and distributed freely, subject to the limited conditions
- described in its source file.
- X
- Victor A. Abell
- Purdue University Computing Center
- November 22, 1991
- END_OF_FILE
- if test 1564 -ne `wc -c <'00DIST'`; then
- echo shar: \"'00DIST'\" unpacked with wrong size!
- fi
- # end of '00DIST'
- fi
- if test -f '00README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'00README'\"
- else
- echo shar: Extracting \"'00README'\" \(1524 characters\)
- sed "s/^X//" >'00README' <<'END_OF_FILE'
- X Making and Installing lsof 1.0
- X
- The Makefile contains rules for making Makefile's for specific UNIX versions
- X-- e. g., ``make Makefile.sun''. If none of the supplied rules fits your
- configuration, the Makefile has comments about the strings that you may need
- to change. You may need to check your cpp documentation to see if the standard
- symbol that lsof.c assumes for your system is defined. As an example, if the
- X``hpux'' symbol is defined by cpp, to compile lsof under HP-UX 8.x, you need
- to declare:
- X
- X SYSDEFS = -DHPUX8
- X
- Set the following Makefile strings for installing lsof:
- X
- X BIN destination directory for the install rule
- X CDEFS compiler definitions
- X DEBUG compiler optimizations -- e. g., -g or -O
- X DOC destination directory for the PUCC-specific mkcat rule
- X GRP group (may need to be the group that can read
- X /dev/kmem) (see MODE)
- X LDLIB special loader library -- e. g., -lkvm for SunOS
- X MODE 0755 + 2000 if setgid access needed to /dev/kmem,
- X and +4000 if any user should be able to search for
- X any file, regardless of ownership or permissions
- X SHELL the shell make(1) should use -- usually /bin/sh
- X
- You may also have to change the install rule to use separate commands --
- cp, chown, chgrp, chmod -- if your system's install command does not honor
- Berkeley syntax.
- X
- If your HP-UX hp9000s800 system does not have the <sys/fss.h> header file
- add ``-I.'' to the CDEFS rule -- e. g.,
- X
- X CDEFS= -I.
- X
- X
- Vic Abell <abe@mace.cc.purdue.edu>
- Purdue University Computing Center (PUCC)
- November 22, 1991
- END_OF_FILE
- if test 1524 -ne `wc -c <'00README'`; then
- echo shar: \"'00README'\" unpacked with wrong size!
- fi
- # end of '00README'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(3120 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# $Id: Makefile,v 1.1 91/11/22 09:21:07 abe Exp $
- X#
- X# Makefile for lsof(8L)
- X#
- X# Victor A. Abell <abe@mace.cc.purdue.edu>
- X# Purdue University Computing Center (PUCC)
- X
- X# Note: the following cpp (or equivalent) definitions are assumed.
- X#
- X# AIX 3.1.[357] -D_IBMR2
- X# HP-UX 7.x -Dhpux
- X# HP-UX 8.x -Dhpux
- X# Purdue DYNIX 3.0.12 -DDYNIX
- X# Sequent DYNIX 3.0.12 -DDYNIX
- X# NeXTStep 2.1 -DNeXT
- X# SunOS 4.1.1 -Dsun
- X#
- X# See SYSDEFS for other, specific definitions that may be required.
- X#
- X# Hint: see if there is a specific Makefile.<system> rule that is
- X# suitable for your installation -- e. g., Makefile.hpux7 or
- X# Makefile.sun.
- X
- X# Some make(1)'s need to be told explicitly what shell to use.
- X
- SHELL= /bin/sh
- X
- X# Define system-specific values in SYSDEFS.
- X#
- X# System Needs
- X# HP-UX 7.x SYSDEFS= -DHPUX7
- X# HP-UX 8.x SYSDEFS= -DHPUX8
- X# Sequent DYNIX 3.0.12 SYSDEFS= -DSEQUENT
- X
- SYSDEFS=
- X
- BIN= ${DESTDIR}/usr/local/etc
- DOC= ${DESTDIR}/usr/man
- GRP= kmem
- X
- DEBUG= -O
- X
- X# If your HP-UX hp9000s800 system does not have the <sys/fss.h> header
- X# file, add ``-I.'' to CDEFS -- e. g.,
- X#
- X# CDEFS= -I.
- X
- CDEFS=
- X
- CFLAGS= ${DEBUG} ${CDEFS} ${SYSDEFS}
- X
- X# Define a special loader library.
- X#
- X# System Needs
- X# HPUX7 LDLIB= -lBSD
- X# SunOS LDLIB= -lkvm
- X
- LDLIB=
- X
- HDR=
- SRC= lsof.c
- DEP= ${SRC}
- MAN= lsof.8
- OBJ= lsof.o
- SOURCE= Makefile ${HDR} ${SRC}
- X
- all: lsof
- X
- clean: FRC
- X rm -f Makefile.* lsof *.o a.out core errs tags
- X
- X# The depend rule assumes the availability of PUCC's dependency generator.
- X
- depend: ${SRC} ${HDR} FRC
- X maketd ${CDEFS} ${DEP}
- X
- install: lsof FRC
- X install -c -s -m 2755 -g ${GRP} lsof ${BIN}
- X
- lint: ${SRC} ${HDR} FRC
- X lint ${CDEFS} ${DEP}
- X
- lsof: ${OBJ}
- X ${CC} -o $@ ${CFLAGS} ${OBJ} ${LDLIB}
- X
- X# Generate Makefile for IBM RISC/System 6000.
- X
- Makefile.ibmr2: Makefile
- X sed -e 's@^GRP= kmem@GRP= system@' <Makefile >$@
- X
- X# Generate Makefile for HP-UX 7.x.
- X
- Makefile.hpux7: Makefile
- X sed -e 's@^LDLIB=@LDLIB= -lBSD@' -e 's@^SYSDEFS=@SYSDEFS= -DHPUX7@' <Makefile >$@
- X
- X# Generate Makefile for HP-UX 8.x.
- X
- Makefile.hpux8: Makefile
- X sed -e 's@^SYSDEFS=@SYSDEFS= -DHPUX8@' <Makefile >$@
- X
- X# Generate Makefile for NeXTStep 2.[01].
- X
- Makefile.next2: Makefile
- X sed -e 's@^GRP= kmem@GRP= operator@' <Makefile >$@
- X
- X# Generate Makefile for Sequent's version of DYNIX.
- X
- Makefile.sequent: Makefile
- X sed -e 's@^SYSDEFS=@SYSDEFS= -DSEQUENT@' <Makefile >$@
- X
- X# Generate Makefile for SunOS 4.1.1.
- X
- Makefile.sun: Makefile
- X sed -e 's@^LDLIB=@LDLIB= -lkvm@' <Makefile >$@
- X
- X# The mkcat rule assumes the availability of PUCC's manual page handler.
- X
- mkcat: ${MAN} ${DOC} FRC
- X mkcat -r${DOC} ${MAN}
- X
- print: source FRC
- X lpr -J'lsof source' ${SOURCE}
- X
- source: ${SOURCE} FRC
- X
- X# The following rule assumes the use of RCS.
- X
- spotless: clean
- X rcsclean ${SOURCE}
- X
- tags: ${SRC} ${HDR} FRC
- X ctags -t ${SRC} ${HDR}
- X
- X# The following rule assumes the use of RCS.
- X
- X${SOURCE}:
- X co -q $@
- X
- XFRC:
- X
- X# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
- X
- lsof.o: lsof.c
- X
- X# *** Do not add anything here - It will go away. ***
- END_OF_FILE
- if test 3120 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'lsof.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lsof.8'\"
- else
- echo shar: Extracting \"'lsof.8'\" \(8577 characters\)
- sed "s/^X//" >'lsof.8' <<'END_OF_FILE'
- X.TH LSOF 8 PUCC
- X.if !\n()P .nr )P 1v
- X.SH NAME
- lsof \- list open files
- X.SH SYNOPSIS
- X.B lsof
- X[
- X.B \-d
- X] [
- X.B \-h
- X] [
- X.B \-l
- X] [
- X.B \-n
- X] [
- X.B \-N
- X] [
- X.BI \-p " l"
- X] [
- X.B \-s
- X] [
- X.B \-t
- X] [
- X.BI \-u " l"
- X] [
- X.BI \-U
- X]
- X.I names
- X.SH DESCRIPTION
- X.I Lsof
- lists information about files opened by processes for the following
- operating systems:
- X.PP
- X.nf
- X AIX 3.1.3, 3.1.5 and 3.1.7 for the IBM RISC/System 6000
- X Dynix 3.0.12 and 3.1.2 for the Sequent Symmetry S81
- X HP\-UX 7.x for the Hewlett Packard 9000/300 and 9000/800
- X HP\-UX 8.x for the Hewlett Packard 9000/300, 9000/700 and 9000/800
- X NeXTStep 2.0 and 2.1 for the NeXT Work Station
- X SunOS 4.1.1
- X.fi
- X.PP
- An open file may be a regular file, a directory, a character special
- file, or a network file (Internet socket, NFS file or Unix domain socket.)
- A specific file may be selected by its path
- X.IR name .
- X.SH OPTIONS
- In the absence of any options,
- X.I lsof
- lists all open files belonging to all active processes.
- X.PP
- If any list request option is specified, all other lists must be
- specifically requested \- e. g., if
- X.B \-n
- is specified for the listing of Internet network files, NFS files won't be
- listed unless
- X.B \-N
- is also specified;
- or if a user list is specified with the
- X.B \-u
- option, Internet network files and Unix domain socket files belonging to
- users not in the list won't be listed unless the
- X.B \-n
- and
- X.B \-U
- options are also specified.
- X.TP \w'names'u+4
- X.B \-d
- This option selects the production of error messages about unreadable
- subdirectories of the
- X.I /dev
- directory.
- Under SunOS, for example, the
- X.I /dev/lpd
- subdirectory is unreadable for security reasons.
- When building its cache of names and device numbers for devices,
- X.I lsof
- skips unreadable subdirectories silently unless
- X.B \-d
- is specified.
- X.TP
- X.B \-h
- This option selects a brief usage (help) output list.
- X.TP
- X.B \-l
- This option inhibits the conversion of user ID numbers to login names.
- X.TP
- X.B \-n
- This option selects the listing of Internet network files.
- X.TP
- X.B \-N
- This option selects the listing of NFS files.
- X.TP
- X.BI \-p " l"
- This option selects the listing of files for the processes whose ID numbers
- are in the comma\-separated list `l' \- e. g., ``123'' or ``123,456''.
- X(There should be no spaces in the list.)
- X.TP
- X.B \-s
- This option removes the SIZE column from the output, shortening
- output lines by nine characters.
- X.TP
- X.B \-t
- This option specifies that
- X.I lsof
- should produce terse output with process identifiers only and no header \-
- e. g., so that the output may be piped to
- X.IR kill (1).
- X.TP
- X.BI \-u " l"
- This option selects the listing of files for the user whose login names
- or user ID numbers are in the comma\-separated list `l' \- e. g., ``abe'',
- or ``548,root''.
- X(There should be no spaces in the list.)
- X.TP
- X.B \-U
- This option selects the listing of Unix domain socket files.
- X.TP
- X.I names
- These are path names of specific files to list.
- Symbolic links are resolved before use.
- X.IP
- If a
- X.I name
- is the mount point of a file system or the device of the mount point of a
- file system,
- X.I lsof
- will list all the files open on the file system.
- If a
- X.I name
- is the base name of a family of multiplexed files \- e. g, AIX's
- X.IR /dev/pts " \-"
- X.I lsof
- will list all the associated multipled files on the device that
- are open \- e. g.,
- X.IR /dev/pts/1 ,
- X.IR /dev/pts/2 ,
- etc.
- X.IP
- If a
- X.I name
- is none of the above,
- X.I lsof
- will list any open files whose device and inode match that of the
- specified path
- X.IR name .
- X.SH OUTPUT
- X.I Lsof
- lists for each open file:
- X.TP \w'COMMAND'u+4
- COMMAND
- contains the first nine characters of the name of the Unix command associated
- with the process.
- X.TP
- PID
- is the Process IDentification number of the process.
- X.TP
- USER
- is the user ID number or login name of the user to whom the process
- belongs.
- X(See the
- X.B \-l
- option.)
- X.TP
- XFD
- is the File Descriptor number of the file or ``cwd'' if it is the
- current working directory of the process.
- XFD is followed by these characters for file locks:
- X.IP
- X \fBr\fP for read lock on part of the file;
- X.br
- X \fBR\fP for a read lock on the entire file;
- X.br
- X \fBw\fP for a write lock on part of the file;
- X.br
- X \fBW\fP for a write lock on the entire file.
- X.TP
- TYPE
- is the type of the vnode associated with the file (see <sys/vnode.h>);
- X.IP
- or ``inet'' for an Internet domain socket;
- X.IP
- or ``unix'' for a Unix domain socket.
- X.TP
- DEVICE
- contains the major and minor device numbers for a character special, block
- special, regular, directory or NFS file (an HP\-UX minor device number is
- listed in hexadecimal);
- X.IP
- or the protocol control block address of a Unix or Internet domain file
- X(the number that appears in
- X.IR netstat (1)'s
- X.B \-A
- output).
- X.TP
- SIZE
- is the size of the file in bytes, when it is known.
- This column may be removed from the output by specifying the
- X.B \-s
- option.
- X.TP
- INODE
- is the inode number of a local file;
- X.IP
- or the inode number of an NFS file in the server host;
- X.IP
- or the Internet protocol type \- e. g, ``TCP''.
- X.TP
- NAME
- is the name of the mount point and file system on which the file resides;
- X.IP
- or the name of a file specified in the
- X.I names
- option (after any symbolic links have been resolved);
- X.IP
- or the name of a character special or block special device;
- X.IP
- or the local and remote Internet addresses of a network file;
- X.IP
- or the address of a Unix domain socket;
- X.IP
- or the local and remote mount point names of an NFS file.
- X.SH DIAGNOSTICS
- XErrors are identified with messages on the standard error file.
- X.PP
- X.I Lsof
- returns a one (1) if any error was detected, including the failure to
- locate any
- X.IR names .
- It returns a zero (0) if no errors were detected and if it was able to
- list information about all the specified
- X.IR names .
- X.SH EXAMPLES
- To list all open files, use:
- X.IP
- lsof
- X.PP
- To list all open Internet and Unix domain files, use:
- X.IP
- lsof -n -U
- X.PP
- To list all open files for login name ``abe'', user ID 1234, process 123,
- process 456 and process 789, use:
- X.IP
- lsof -p 789,456,123 -u 1234,abe
- X.PP
- To list all open files on device /dev/hd4, use:
- X.IP
- lsof /dev/hd4
- X.PP
- To find the process that has /u/abe/foo open, use:
- X.IP
- lsof /u/abe/foo
- X.PP
- To send a SIGHUP to the processes that have /u/abe/bar open, use:
- X.IP
- kill -HUP `lsof -t /u/abe/bar`
- X.SH BUGS
- Since
- X.I lsof
- reads kernel memory in its search for open files, rapid changes in kernel
- memory may produce unpredictable results.
- X.PP
- Absence of hardware or software configurations for some operating systems
- X\- e. g., HP\-UX 7.x and 8.x and Sequent Dynix 3.1.2 \- means that
- X.I lsof
- has not been fully tested on them.
- X.PP
- The lock status character (following the file descriptor) is derived under
- AIX from a test of only the first filock structure of the gnode
- X(see <sys/flock.h> and <sys/gnode.h>).
- X.PP
- X.I Lsof
- can't search for any file by
- X.I name
- unless it is installed with root set-UID permission.
- Otherwise it is restricted to searching for files to which its user
- or its set-GID group (if any) have access.
- X.PP
- X.I Lsof
- startup time is long on systems where scanning the
- X.I /dev
- directory is a slow operation.
- X.PP
- Output lines are sometimes greater than eighty characters \- e. g.,
- for completed Internet connections or NFS files \- causing the output
- listing to be irregularly spaced.
- The
- X.B \-s
- option may be specified to remove the SIZE column, shortening output
- lines by nine characters.
- X.PP
- If there are files or subdirectories in
- X.I /dev
- that
- X.I lsof
- can't
- X.IR stat (2)
- or read, it will ignore them without complaint, unless the
- X.B \-d
- option is selected.
- Whether
- X.I lsof
- complains or not, it is unable to report major and minor device numbers
- for the entries it can't access.
- X.SH FILES
- X.TP \w'/dev/swap'u+16
- X/dev/drum system paging device
- X.TP
- X/dev/kmem kernel virtual memory device
- X.TP
- X/dev/mem physical memory device
- X.TP
- X/dev/swap system paging device
- X.SH AUTHORS
- X.I Lsof
- was written by Victor A. Abell of the Purdue University Computing Center
- X(PUCC), based on the
- X.I fstat
- and
- X.I ofiles
- programs.
- He acknowledges his debt to the work of Dan Bernstein, Michael ``Ford''
- Ditto, Tom Dunigan, Alexander Dupuy, Vik Lall, Ray Moody, C. Spencer,
- Michael Spitzer and those who wrote Berkeley's
- X.I fstat
- program, all contributors to
- X.I lsof's
- predecessors.
- He thanks Doug McKenzie for his HP\-UX
- X.I proctor
- program and Rich Kulawiec for pointing it out.
- XFinally, he is grateful to Jim Cooper, J. Nelson Howell, Markus
- Lautenbacher, Wendy Lin, Andreas Luik, Fletcher Mattox, Michael Mackenzie,
- Jeff Stewart and Patrick Wolfe for their help in developing and
- improving
- X.IR lsof .
- X.SH SEE ALSO
- ff(1),
- fstat(8),
- fuser(1),
- kill(1),
- netstat(1),
- ofiles(8L),
- ps(1).
- lsof.8
- END_OF_FILE
- if test 8577 -ne `wc -c <'lsof.8'`; then
- echo shar: \"'lsof.8'\" unpacked with wrong size!
- fi
- # end of 'lsof.8'
- fi
- if test -f 'lsof.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lsof.c'\"
- else
- echo shar: Extracting \"'lsof.c'\" \(79705 characters\)
- sed "s/^X//" >'lsof.c' <<'END_OF_FILE'
- X/*
- X * lsof.c - list open files
- X */
- X
- X
- X/*
- X * Lsof lists files opened by processes of:
- X *
- X * AIX 3.1.[357] (#define _IBMR2)
- X * Purdue DYNIX 3.0.12 (#define DYNIX)
- X * Sequent DYNIX 3.0.12 (#define DYNIX, #define SEQUENT)
- X * Sequent DYNIX 3.1.2 (#define DYNIX31)
- X * HP-UX 7.x (#define hpux, #define HPUX7)
- X * HP-UX 8.x (#define hpux, #define HPUX8)
- X * NeXTStep 2.[01] (#define NeXT)
- X * SunOS 4.1.1 (#define sun)
- X */
- X
- X/*
- X * Copyright 1991 Purdue Research Foundation, West Lafayette, Indiana
- X * 47907. All rights reserved.
- X *
- X * Written by Victor A. Abell
- X *
- X * This software is not subject to any license of the American Telephone
- X * and Telegraph Company or the Regents of the University of California.
- X *
- X * Permission is granted to anyone to use this software for any purpose on
- X * any computer system, and to alter it and redistribute it freely, subject
- X * to the following restrictions:
- X *
- X * 1. Neither the author nor Purdue University are responsible for any
- X * consequences of the use of this software.
- X *
- X * 2. The origin of this software must not be misrepresented, either by
- X * explicit claim or by omission. Credit to the author and Purdue
- X * University must appear in documentation and sources.
- X *
- X * 3. Altered versions must be plainly marked as such, and must not be
- X * misrepresented as being the original software.
- X *
- X * 4. This notice may not be removed or altered.
- X */
- X
- X#if !defined(lint)
- static char copyright[] =
- X"@(#) Copyright 1991 Purdue Research Foundation.\nAll rights reserved.\n";
- X#endif
- X
- static char Version[] = "1.0";
- X
- X
- X/*
- X * Usage:
- X *
- X * lsof [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t] [-u l] [-U] [names]
- X *
- X * where:
- X *
- X * -d Issue error messages about unreadable /dev
- X * subdirectories.
- X *
- X * -h List help.
- X *
- X * -l Do not convert User ID numbers to login names.
- X *
- X * -n List Internet network files.
- X *
- X * -N List NFS files.
- X *
- X * -p l List files for Process IDentifier list l -- comma
- X * separated list of numbers.
- X *
- X * -s Do not display file size.
- X *
- X * -t List terse output -- i. e., Process ID numbers without
- X * a header.
- X *
- X * -u l List files for user list l -- comma separated list of
- X * login names or User IDentification numbers.
- X *
- X * -U List Unix domain sockets.
- X *
- X * names are the path names of file systems, mount points,
- X * devices and files to locate.
- X */
- X
- X#if defined(NeXT) && !defined(MACH)
- X/*
- X * The definition of MACH for the NeXT is required for proper header
- X * file configuration -- i. e., some header files have ``#ifdef MACH''
- X * statements that affect the size of kernel structures.
- X */
- X
- X#define MACH 1
- X#endif
- X
- X#include <sys/types.h>
- X#include <sys/param.h>
- X
- X#include <ctype.h>
- X#include <errno.h>
- X#include <pwd.h>
- X#include <setjmp.h>
- X#include <stdio.h>
- X
- X#include <sys/domain.h>
- X#include <sys/mbuf.h>
- X#include <sys/protosw.h>
- X#include <sys/socket.h>
- X#include <sys/socketvar.h>
- X#include <sys/stat.h>
- X#include <sys/time.h>
- X#include <sys/un.h>
- X#include <sys/unpcb.h>
- X#include <sys/vfs.h>
- X#include <sys/vnode.h>
- X#include <net/route.h>
- X#include <netinet/in.h>
- X#include <netinet/in_pcb.h>
- X
- X#if defined(DYNIX31)
- X#undef SEQUENT
- X#undef DYNIX
- X#define DYNIX
- X#endif
- X
- X#if defined(DYNIX)
- X#include <mntent.h>
- X#include <strings.h>
- X#include <nlist.h>
- X#include <nfs/nfs.h>
- X#include <nfs/nfs_clnt.h>
- X#include <nfs/rnode.h>
- X#include <sys/dir.h>
- X#include <sys/file.h>
- X#include <sys/proc.h>
- X#define KERNEL
- X#include <sys/file.h>
- X#include <sys/inode.h>
- X#include <ufs/mount.h>
- X#undef KERNEL
- X#include <sys/user.h>
- X
- X#if !defined(DYNIX31)
- X/*
- X * This is from sys/user.h. It's ifdef KERNEL, though, and defining
- X * KERNEL for user.h breaks other things.
- X *
- X * Open-file table extension object structure.
- X */
- X
- struct ofile_ext {
- X struct ofile_ext *oe_next; /* list of unused entries */
- X short oe_nofile; /* # ofile entries */
- X short oe_refcnt; /* # proc's sharing this ext */
- X short oe_ccount; /* # sharing proc's in memory */
- X swblk_t oe_swaddr; /* disk address when swapped */
- X sema_t oe_mutex; /* misc mutex */
- X struct ofile *oe_ofile; /* array of open files */
- X};
- X#endif
- X
- X#endif
- X
- X#if defined(hpux)
- X#include <stdlib.h>
- X#include <dirent.h>
- X#include <mntent.h>
- X#include <string.h>
- X#include <nlist.h>
- X#include <rpc/types.h>
- X#include <nfs/nfs.h>
- X#include <nfs/nfs_clnt.h>
- X#include <nfs/rnode.h>
- X#include <nfs/snode.h>
- X#include <sys/file.h>
- X#include <sys/inode.h>
- X
- X#if defined(HPUX8)
- X#include <sys/pstat.h>
- X#endif
- X
- X#include <sys/resource.h>
- X#include <sys/proc.h>
- X#include <sys/vmmac.h>
- X#include <sys/user.h>
- X
- X/*
- X * This is from <sys/mount.h>, defined under the _KERNEL symbol.
- X * Unfortunately, defining _KERNEL causes <sys/mount.h> to include
- X * other header files not in <sys>.
- X */
- X
- struct mount {
- X struct mount *m_hforw; /* forward hash pointer */
- X struct mount *m_hback; /* backward hash pointer */
- X struct mount *m_rhforw; /* forward hash pointer for real device */
- X struct mount *m_rhback; /* backward hash pointer for real device */
- X struct vfs *m_vfsp; /* vfs structure for this filesystem */
- X dev_t m_dev; /* device mounted */
- X };
- X#endif
- X
- X#if defined(_IBMR2)
- X#include <stdlib.h>
- X#include <string.h>
- X#include <dirent.h>
- X#if !defined(_KERNEL)
- X#define _KERNEL 1
- X#endif
- X#include <sys/file.h>
- X#undef _KERNEL
- X#include <sys/mntctl.h>
- X#include <sys/sysmacros.h>
- X#include <sys/vattr.h>
- X#include <sys/vmount.h>
- X#include <procinfo.h>
- X#include <nfs/rnode.h>
- X
- X/*
- X * AIX 3.1.[357] doesn't supply the necessary cdrnode.h.
- X */
- X
- struct cdrnode {
- X caddr_t f1[4];
- X struct gnode f2;
- X dev_t f3;
- X ino_t cn_inumber; /* inode number */
- X caddr_t f4;
- X cnt_t f5[2];
- X u_short f6;
- X uint f7[2];
- X uchar f8[3];
- X off_t cn_size; /* size of file in bytes */
- X};
- X#endif
- X
- X#if defined(NeXT)
- X#include <c.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <mntent.h>
- X#include <nlist.h>
- X#include <signal.h>
- X#include <kern/queue.h>
- X#include <sys/policy.h>
- X#if !defined(NCPUS)
- X#define NCPUS 1
- X#endif
- X#include <kern/task.h>
- X#include <netinet/in.h>
- X#include <rpc/rpc.h>
- X#include <rpc/xdr.h>
- X#include <nfs/nfs.h>
- X#include <nfs/nfs_clnt.h>
- X#include <nfs/rnode.h>
- X#include <sys/dir.h>
- X#include <sys/domain.h>
- X#if !defined(KERNEL)
- X#define KERNEL
- X#endif
- X#include <sys/file.h>
- X#undef KERNEL
- X#include <ufs/mount.h>
- X#include <sys/protosw.h>
- X#include <sys/socket.h>
- X#include <sys/socketvar.h>
- X#include <sys/stat.h>
- X#include <sys/ucred.h>
- X#include <sys/un.h>
- X#include <sys/unpcb.h>
- X#if !defined(SHOW_UTT)
- X#define SHOW_UTT
- X#endif
- X#include <sys/user.h>
- X#undef SHOW_UTT
- X#include <sys/proc.h>
- X#include <sys/vfs.h>
- X#include <ufs/inode.h>
- X
- X/*
- X * The following substitution compensates for the snode.h that NeXT does
- X * not supply in NeXTStep 2.0 or 2.1. The value of interest is s_realvp.
- X */
- X
- struct snode {
- X struct snode *s_next; /* must be first */
- X struct vnode s_vnode; /* vnode associated with this snode */
- X struct vnode *s_realvp; /* vnode for the fs entry (if any) */
- X};
- X#endif
- X
- X#if defined(sun)
- X#include <stdlib.h>
- X#include <string.h>
- X#include <dirent.h>
- X#include <kvm.h>
- X#include <mntent.h>
- X#include <nlist.h>
- X#include <signal.h>
- X#include <rpc/types.h>
- X#include <nfs/nfs.h>
- X#include <nfs/rnode.h>
- X#include <specfs/snode.h>
- X#include <sys/proc.h>
- X#include <sys/sysmacros.h>
- X#include <sys/user.h>
- X#include <tmpfs/tmpnode.h>
- X#include <ufs/inode.h>
- X#include <ufs/mount.h>
- X#if !defined(KERNEL)
- X#define KERNEL 1
- X#endif
- X#include <sys/file.h>
- X#include <specfs/fifonode.h>
- X#undef KERNEL
- X#endif
- X
- extern int errno;
- X
- extern struct passwd *getpwnam(), *getpwuid();
- X
- X#if defined(DYNIX) || defined(sun)
- extern int nlist();
- X#endif
- X
- extern char *optarg;
- extern int optind;
- extern char *sys_errlist[];
- X
- X#define DEVINCR 1024 /* device table malloc() increment */
- X#define IPROTOL 5 /* Internet protocol length */
- X#define LOGINML 8 /* login name length */
- X#define PIDINCR 10 /* PID table malloc() increment */
- X#define STATTMO 5 /* stat() timeout in seconds */
- X#define UIDINCR 10 /* UID table malloc() increment */
- X#define USERPRTL 8
- X#define V_REG 0 /* vnode is regular */
- X#define V_FIFO 1 /* vnode is a FIFO */
- X#define V_NFS 2 /* vnode is an NFS file system */
- X#define V_STREAM 3 /* vnode is a stream */
- X#define V_TMP 4 /* vnode is a tmpfs */
- X
- X#if defined(DYNIX)
- X#define MALLOC_P char
- X#define FREE_P MALLOC_P
- X#define MALLOC_S unsigned
- X#define N_UNIX "/dynix"
- X#define QSORT_P char
- X#define STRNCPY_L int
- X#define SWAP "/dev/drum"
- X#define U_SIZE sizeof(struct user)
- X
- X#if defined(DYNIX31)
- X#define strchr index
- X#define strrchr rindex
- X#endif
- X
- X#if defined(SEQUENT)
- X#define strchr index
- X#define strrchr rindex
- X#define uid_t int
- X#define unp_addr unp_remaddr
- X#endif
- X
- X#endif
- X
- X#if defined(hpux)
- X#define MALLOC_P char
- X#define FREE_P void
- X#define MALLOC_S unsigned
- X#define MOUNTED MNT_MNTTAB
- X#define N_UNIX "/hp-ux"
- X#define PROCSIZE sizeof(struct proc)
- X#define QSORT_P void
- X#define STRNCPY_L size_t
- X#define SWAP "/dev/swap"
- X
- X#if defined(HPUX7)
- X#define unp_addr unp_locaddr
- X/*
- X * HP-UX 7.x SWAP must be read in DEV_BSIZE chunks.
- X */
- X#define U_SIZE (((DEV_BSIZE+sizeof(struct user))/DEV_BSIZE)*DEV_BSIZE)
- X#endif
- X
- X#if defined(HPUX8)
- X#define U_SIZE sizeof(struct user)
- X#endif
- X
- X#endif
- X
- X#if defined(_IBMR2)
- X#define MALLOC_P void
- X#define FREE_P MALLOC_P
- X#define MALLOC_S size_t
- X#define PROCSIZE sizeof(struct procinfo)
- X#define QSORT_P void
- X#define STRNCPY_L int
- X#define U_SIZE sizeof(struct user)
- X#endif
- X
- X#if defined(NeXT)
- X#define MALLOC_P void
- X#define FREE_P MALLOC_P
- X#define MALLOC_S size_t
- X#define PROCSIZE sizeof(struct proc)
- X#define QSORT_P void
- X#define STRNCPY_L int
- X#define U_SIZE sizeof(struct user)
- X#if !defined(VMUNIX)
- X#define VMUNIX "/mach"
- X#endif
- X#endif
- X
- X#if defined(sun)
- X#define CLONEMAJ 37 /* major device number for clone device */
- X#define MALLOC_P char
- X#define FREE_P MALLOC_P
- X#define MALLOC_S unsigned
- X#define N_UNIX "/vmunix"
- X#define PROCSIZE sizeof(struct proc)
- X#define QSORT_P char
- X#define STRNCPY_L int
- X#define U_SIZE sizeof(struct user)
- X#endif
- X
- X
- X/*
- X * Global storage definitions
- X */
- X
- X#if defined(sun)
- struct clone {
- X struct dev *dp; /* pointer to device entry in Devtp[] */
- X struct clone *next;
- X
- X} *Clone = NULL;
- X#endif
- X
- char *Command; /* command name */
- dev_t Dev; /* device number */
- char Devch[32]; /* alternate characters for device printing */
- X
- struct dev {
- X dev_t rdev; /* device */
- X char *name; /* name */
- X
- X} *Devtp = NULL; /* device table pointer */
- X
- char Fd[8]; /* file descriptor for printing */
- int Fdev = 0; /* have device number flag */
- int Fdevmsg = 0; /* -d flag status */
- int Fhelp = 0; /* -h flag status */
- int Fnet = 0; /* -n flag status */
- int Fnfs = 0; /* -N flag status */
- int Fprint = 0; /* print line flag */
- int Fsize = 1; /* -s flag status */
- int Fterse = 0; /* -t flag status */
- int Funix = 0; /* -U flag status */
- int Futol = 1; /* -l flag status */
- int Hdr = 0; /* header print status */
- long Inode = -1l; /* inode number
- X * -1: none (don't print anything)
- X * -2: blank (print spaces) */
- char Iproto[IPROTOL+1]; /* Internet protocol name */
- X
- X#if defined(sun)
- kvm_t *Kd; /* kvm descriptor */
- X#endif
- X
- int Kmem = -1; /* /dev/kmem file descriptor */
- X
- struct l_vfs {
- X
- X struct vfs *addr; /* kernel address */
- X
- X#if defined(DYNIX) || defined(hpux) || defined(_IBMR2)
- X dev_t dev; /* device */
- X#endif
- X char *dir; /* mounted directory */
- X char *fsname; /* file system name */
- X
- X#if defined(_IBMR2)
- X int vmt_flags; /* vmount flags */
- X int vmt_gfstype; /* vmount gfs type */
- X#endif
- X
- X struct l_vfs *next; /* next entry pointer */
- X} *Lvfs = NULL; /* local vfs structure table */
- X
- X#if defined(HPUX7)
- int Mem = -1; /* /dev/mem file descriptor */
- X#endif
- X
- char Lock = ' '; /* lock status */
- X
- struct mounts {
- X dev_t dev; /* st_dev */
- X char *dir; /* directory */
- X char *fsname; /* file system */
- X ino_t inode; /* st_ino */
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
- X u_short mode; /* st_mode */
- X#endif
- X
- X#if defined(hpux) || defined(sun)
- X mode_t mode; /* st_mode */
- X#endif
- X
- X struct mounts *next; /* forward link */
- X dev_t rdev; /* st_rdev */
- X
- X} *Mtab = NULL; /* mounted devices */
- X
- int Mxpid = 0; /* maximum PID table entries */
- int Mxuid = 0; /* maximum UID table entries */
- char Namech[1024]; /* name characters for printing */
- int Ndev = 0; /* number of device table entries */
- X
- X#if defined(DYNIX)
- struct nlist Nl[] = {
- X { "_proc" },
- X#define X_PROC 0
- X {"_nproc"},
- X#define X_NPROC 1
- X {"_nfs_vnodeops"},
- X#define X_NFS_OPS 2
- X { "" },
- X};
- X#endif
- X
- X#if defined(hpux)
- struct nlist Nl[] = {
- X
- X#if defined(hp9000s300)
- X {"_proc"},
- X#define X_PROC 0
- X {"_nproc"},
- X#define X_NPROC 1
- X {"_nfs_vnodeops"},
- X#define X_NFS_OPS 2
- X
- X#if defined(HPUX7)
- X {"_Usrptmap"},
- X#define X_USRPTMAP 3
- X {"_usrpt"},
- X#define X_USRPT 4
- X#endif
- X
- X#endif
- X
- X#if defined(hp9000s800)
- X {"proc"},
- X#define X_PROC 0
- X {"nproc"},
- X#define X_NPROC 1
- X {"nfs_vnodeops"},
- X#define X_NFS_OPS 2
- X
- X#if defined(HPUX7)
- X {"ubase"},
- X#define X_UBASE 3
- X {"npids"},
- X#define X_NPIDS 4
- X#endif
- X
- X#endif
- X
- X { "" }
- X};
- X#endif
- X
- X#if defined(NeXT)
- X
- static struct nlist Nl[] = {
- X { {"_allproc"}, 0, 0, 0 },
- X#define X_ALLPROC 0
- X { {"_nfs_vnodeops"}, 0, 0, 0},
- X#define X_NFS_OPS 1
- X { {""}, 0, 0, 0 },
- X};
- X#endif
- X
- X#if defined(sun)
- struct nlist Nl[] = {
- X {"_nfs_vnodeops"},
- X#define X_NFS_OPS 0
- X { "_tmp_vnodeops"},
- X#define X_TMP_OPS 1
- X { "" }
- X};
- X#endif
- X
- int Npid = 0; /* -p flag count */
- int Nuid = 0; /* -u flag count */
- X
- X#if defined(HPUX7) && defined(hp9000s800)
- int npids; /* number of PIDs (for uvadd()) */
- struct proc *proc; /* process table address (for uvadd()) */
- X#endif
- X
- X#if defined(hpux)
- long Procaddr; /* kernel process table entry address */
- X#endif
- X
- struct dev **Sdev = NULL; /* pointer to device table pointers, sorted
- X * by device */
- X
- struct sfile {
- X char *name; /* file name */
- X char *devnm; /* device name (optional) */
- X dev_t dev; /* device */
- X
- X#if defined(_IBMR2)
- X chan_t ch; /* channel (last path component, if numeric) */
- X#endif
- X
- X u_short mode; /* S_IFMT mode bits from stat() */
- X int type; /* file type: 0 = file system
- X * 1 = regular file */
- X ino_t i; /* inode number */
- X int f; /* file found flag */
- X struct sfile *next; /* link to next entry */
- X
- X} *Sfile = NULL; /* chain of files to search for */
- X
- off_t Size; /* file size */
- int Size_def; /* file size is defined */
- int *Spid = NULL; /* Process IDs to search for */
- int *Suid = NULL; /* User IDs to search for */
- X
- X#if defined(DYNIX) || defined(hpux)
- int Swap = -1; /* swap device file descriptor */
- X#endif
- X
- int Pid; /* Process ID */
- char *Pn; /* program name */
- X
- jmp_buf Tmo_jbuf; /* jump buffer for mount stat timeout */
- X
- char Type[8]; /* type for printing */
- char User[USERPRTL+1]; /* User ID */
- X
- X#if defined(HPUX7) && defined(hp9000s300)
- struct pte *Usrptmap; /* user page table map pointer */
- struct pte *usrpt; /* user page table pointer
- X * (for bktomx from vmmac.h) */
- X#endif
- X
- X#if defined(HPUX7) && defined(hp9000s800)
- struct user *ubase; /* user area base (for uvadd()) */
- X#endif
- X
- int Vtype; /* vnode type (see V_* symbols) */
- X
- X
- int compdev(), getchan(), isfile(), kread(), readinode(),
- X readlink(), readrnode(), readvnode(), statsafely();
- X
- char *endnm(), isglocked();
- X
- struct l_vfs *readvfs();
- X
- void printchdevname(), printfile(), printinaddr(), printiproto(),
- X printline(), printsocket(), printuid(), printvnode(), readdev(),
- X readmnt(), stkdir();
- X
- X#if defined(DYNIX)
- char *malloc(), *realloc();
- int stattimeout();
- void completevfs();
- u_short ntohs();
- X#endif
- X
- X#if defined(hpux)
- int readsnode();
- off_t lseek();
- void completevfs(), stattimeout();
- X#endif
- X
- X#if defined(_IBMR2)
- int readcdrnode(), readgnode();
- void stattimeout();
- X#endif
- X
- X#if defined(NeXT)
- int readsnode();
- void completevfs(), stattimeout();
- X#endif
- X
- X#if defined(sun)
- int readfifonode(), readsnode(), readtnode();
- void completevfs(), stattimeout();
- X#endif
- X
- X/*
- X * Process structure redefinitions
- X */
- X
- X#if defined(_IBMR2)
- X#define p_pid pi_pid
- X#define p_stat pi_stat
- X#define p_uid pi_uid
- X#endif
- X
- X/*
- X * User structure redefinitions
- X */
- X
- X#if defined(NeXT)
- X#define u_comm uu_comm
- X#define u_cdir uu_cdir
- X#endif
- X
- X
- X/*
- X * main() - main program
- X */
- X
- main(argc, argv)
- X int argc;
- X char *argv[];
- X{
- X int c;
- X int err = 0;
- X char *fnm;
- X int fprint;
- X char *fsnm;
- X int ftype;
- X int i;
- X int llen, llenx;
- X struct mounts *mp;
- X char *path;
- X char *s;
- X struct stat sb;
- X int selflg, selpid, seluid;
- X struct sfile *sfp;
- X char syml[MAXPATHLEN];
- X char *symlp;
- X char symlx[MAXPATHLEN];
- X
- X#if defined(DYNIX)
- X long kp;
- X int nf, np;
- X static struct ofile *ofp = NULL;
- X struct proc *p;
- X struct proc ps;
- X int px;
- X struct user *u;
- X struct ofile *uf;
- X unsigned ui;
- X struct user us;
- X static int xnf = 0;
- X
- X#if !defined(DYNIX31)
- X struct ofile_ext ofx;
- X#endif
- X
- X#if defined(DYNIX31)
- X struct ofile_tab oft;
- X#endif
- X
- X#endif
- X
- X#if defined(hpux)
- X
- X#if defined(HPUX7)
- X int k;
- X char us[U_SIZE]; /* must read HP-UX SWAP in DEV_BSIZE chunks */
- X#endif
- X
- X#if defined(HPUX8)
- X struct ofile_t *ofp;
- X struct ofile_t oft;
- X struct user us;
- X#endif
- X
- X int j;
- X long kp;
- X int np;
- X struct proc *p;
- X struct proc ps;
- X int px;
- X struct user *u;
- X#endif
- X
- X#if defined(_IBMR2)
- X int np;
- X struct procinfo *p;
- X struct user *u;
- X struct user us;
- X#endif
- X
- X#if defined(NeXT)
- X MALLOC_S nb;
- X int nf;
- X struct proc *np, *p, *procp, ps;
- X static MALLOC_S pnb = 0;
- X struct task t;
- X struct file **uf = NULL;
- X struct utask *u, ut;
- X#endif
- X
- X#if defined(sun)
- X int nf;
- X struct proc *p;
- X struct user *u;
- X struct file **uf;
- X unsigned ui;
- X static int xnf = 0;
- X static struct file **xuf = NULL;
- X#endif
- X
- X/*
- X * Save program name for messages.
- X */
- X if ((Pn = strrchr(argv[0], '/')) != NULL)
- X Pn++;
- X else
- X Pn = argv[0];
- X/*
- X * Process arguments.
- X */
- X while ((c = getopt(argc, argv, "dhlnNp:stu:U")) != EOF) {
- X switch(c) {
- X
- X case 'd':
- X Fdevmsg = 1;
- X break;
- X case 'h':
- X Fhelp = 1;
- X break;
- X case 'l':
- X Futol = 0;
- X break;
- X case 'n':
- X Fnet = 1;
- X break;
- X case 'N':
- X Fnfs = 1;
- X break;
- X case 'p':
- X if (entpid(optarg))
- X err++;
- X break;
- X case 's':
- X Fsize = 0;
- X break;
- X case 't':
- X Fterse = 1;
- X break;
- X case 'u':
- X if (entuid(optarg))
- X err++;
- X break;
- X case 'U':
- X Funix = 1;
- X break;
- X case '?':
- X err++;
- X break;
- X default:
- X (void) fprintf(stderr, "%s: unknown option (%c)\n",
- X Pn, c);
- X err++;
- X }
- X }
- X/*
- X * Read the mount table and process any file names.
- X */
- X (void) readmnt();
- X for (i = optind; i < argc; i++) {
- X
- X /*
- X * Dereference a symbolic link.
- X */
- X if ((llen = readlink(argv[i], syml, sizeof(syml) - 1)) >= 0) {
- X syml[llen] = '\0';
- X if (argv[i][0] == '/' && syml[0] != '/') {
- X llenx = (strrchr(argv[i], '/') - argv[i]) + 1;
- X if ((llenx + llen + 1) > sizeof(symlx)) {
- X (void) fprintf(stderr,
- X "%s: sym link for %s too long\n",
- X Pn, argv[i]);
- X exit(1);
- X }
- X (void) strncpy(symlx, argv[i],
- X (STRNCPY_L)llenx);
- X (void) strcpy(&symlx[llenx], syml);
- X symlp = symlx;
- X llen += llenx;
- X } else
- X symlp = syml;
- X if ((path = (char *)malloc((MALLOC_S)(llen + 1)))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for sym link of %s\n",
- X Pn, argv[i]);
- X exit(1);
- X }
- X (void) strcpy(path, symlp);
- X } else
- X path = argv[i];
- X /*
- X * Check for file system argument.
- X */
- X for (ftype = 1, mp = Mtab; mp; mp = mp->next) {
- X if (strcmp(mp->dir, path) == 0) {
- X ftype = 0;
- X fnm = path;
- X fsnm = mp->fsname;
- X break;
- X }
- X if (strcmp(mp->fsname, path) == 0) {
- X ftype = 0;
- X fnm = mp->dir;
- X fsnm = path;
- X break;
- X }
- X }
- X if (ftype) {
- X fnm = path;
- X fsnm = NULL;
- X } else {
- X sb.st_dev = mp->dev;
- X sb.st_ino = mp->inode;
- X sb.st_mode = mp->mode;
- X sb.st_rdev = mp->rdev;
- X }
- X /*
- X * Stat the argument to obtain its mode and device.
- X */
- X
- X if (ftype && statsafely(fnm, &sb, STATTMO) != 0) {
- X (void) fprintf(stderr, "%s: status error on %s: %s\n",
- X Pn, fnm, sys_errlist[errno]);
- X err++;
- X continue;
- X }
- X /*
- X * Allocate an sfile structure and fill in the type, inode,
- X * find-flag and linkages.
- X */
- X if ((sfp = (struct sfile *)malloc(sizeof(struct sfile)))
- X == NULL) {
- X (void) fprintf(stderr, "%s: no space for files\n", Pn);
- X exit(1);
- X }
- X sfp->next = Sfile;
- X Sfile = sfp;
- X sfp->type = ftype;
- X sfp->i = sb.st_ino;
- X sfp->f = 0;
- X /*
- X * Store the file name and file system name pointers in the sfile
- X * structure, allocating space as necessary.
- X */
- X if (fnm == NULL || fnm == path)
- X sfp->name = fnm;
- X else {
- X if ((sfp->name = (char *)malloc((MALLOC_S)(strlen(fnm)+1)))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for file name %s\n", Pn, fnm);
- X exit(1);
- X }
- X (void) strcpy(sfp->name, fnm);
- X }
- X if (fsnm == NULL || fsnm == path)
- X sfp->devnm = fsnm;
- X else {
- X if ((sfp->devnm=(char *)malloc((MALLOC_S)(strlen(fsnm)+1)))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for file system name %s\n", Pn, fsnm);
- X exit(1);
- X }
- X (void) strcpy(sfp->devnm, fsnm);
- X }
- X /*
- X * Save the stat() buffer mode value in the sfile structure.
- X * Use st_rdev if the mode value is S_IFBLK or S_IFCHR; otherwise
- X * use st_dev.
- X */
- X sfp->mode = sb.st_mode & S_IFMT;
- X if (sfp->mode == S_IFBLK || sfp->mode == S_IFCHR)
- X sfp->dev = sb.st_rdev;
- X else
- X sfp->dev = sb.st_dev;
- X
- X#if defined(_IBMR2)
- X /*
- X * Save a (possible) AIX multiplexed channel number.
- X */
- X sfp->ch = getchan(path);
- X#endif
- X
- X }
- X/*
- X * List usage if error or if requested.
- X */
- X if (err || Fhelp) {
- X (void) fprintf(stderr,
- X "%s %s usage: [-d] [-h] [-l] [-n] [-N] [-p l] [-s] [-t]",
- X Pn, Version);
- X (void) fprintf(stderr,
- X " [-u l] [-U] [names]\n");
- X (void) fprintf(stderr,
- X "\t-d issue /dev subdirectory error messages\n");
- X (void) fprintf(stderr,
- X "\t-h list help\n");
- X (void) fprintf(stderr,
- X "\t-l do not convert UID's to login names\n");
- X (void) fprintf(stderr,
- X "\t-n list Internet network files\n");
- X (void) fprintf(stderr,
- X "\t-N list NFS files\n");
- X (void) fprintf(stderr,
- X "\t-p l list files for comma-separated Process ID list l\n");
- X (void) fprintf(stderr,
- X "\t-s do not display file size\n");
- X (void) fprintf(stderr,
- X "\t-t terse output -- Process ID numbers and no header\n");
- X (void) fprintf(stderr,
- X "\t-u l list files for comma-separated user list l ");
- X (void) fprintf(stderr,
- X "(names or UIDs)\n");
- X (void) fprintf(stderr,
- X "\t-U list Unix domain sockets\n");
- X (void) fprintf(stderr,
- X "\tnames path names of file systems, mount points, devices");
- X (void) fprintf(stderr,
- X " and\n\t files to locate\n");
- X if (err)
- X exit(1);
- X exit(0);
- X }
- X/*
- X * Open kernel memory accesses.
- X *
- X * Read and build device and mount tables.
- X */
- X if ((Kmem = open("/dev/kmem", O_RDONLY, 0)) < 0) {
- X (void) fprintf(stderr, "%s: can't open /dev/kmem: %s\n",
- X Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X
- X#if defined(HPUX7)
- X if ((Mem = open("/dev/mem", O_RDONLY, 0)) < 0) {
- X (void) fprintf(stderr, "%s: can't open /dev/mem: %s",
- X Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(DYNIX) || defined(HPUX7)
- X if ((Swap = open(SWAP, O_RDONLY, 0)) < 0) {
- X (void) fprintf(stderr, "%s: /dev/drum: %s\n",
- X Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(NeXT)
- X if (nlist(VMUNIX, Nl) < 0) {
- X (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
- X exit(1);
- X }
- X if (Nl[X_ALLPROC].n_value == 0l) {
- X (void) fprintf(stderr, "%s: no address for %s\n",
- X Pn, Nl[X_ALLPROC].n_un.n_name);
- X exit(1);
- X }
- X if (kread((off_t)Nl[X_ALLPROC].n_value, (char *)&procp, sizeof(procp))){
- X (void) fprintf(stderr,
- X "%s: can't read nl[X_ALLPROC].n_un.n_name: %s\n",
- X Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(sun)
- X if ((Kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) == 0) {
- X (void) sprintf("%s: kvm_open: %s", Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X if (nlist(N_UNIX, Nl) < 0) {
- X (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
- X exit(1);
- X }
- X if (Nl[X_NFS_OPS].n_value == 0l) {
- X (void) fprintf(stderr, "%s: no address for %s\n",
- X Pn, Nl[X_NFS_OPS].n_name);
- X exit(1);
- X }
- X#endif
- X
- X (void) readdev();
- X/*
- X * Read the processs table.
- X */
- X
- X#if defined(DYNIX) || defined(hpux)
- X if (nlist(N_UNIX, Nl) < 0) {
- X (void) fprintf(stderr, "%s: can't read namelist\n", Pn);
- X exit(1);
- X }
- X if (Nl[X_PROC].n_value == NULL
- X || kread((off_t)Nl[X_PROC].n_value, (char *)&kp, sizeof(kp))
- X || Nl[X_NPROC].n_value == NULL
- X || kread((off_t)Nl[X_NPROC].n_value, (char *)&np, sizeof(np))
- X || kp == NULL || np == 0) {
- X (void) fprintf(stderr, "%s: can't read proc table info\n",
- X Pn);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(HPUX7) && defined(hp9000s300)
- X if ((Usrptmap = (struct pte *)Nl[X_USRPTMAP].n_value) == NULL) {
- X (void) fprintf(stderr, "%s: can't get kernel's Usrptmap\n", Pn);
- X exit(1);
- X }
- X if ((usrpt = (struct pte *)Nl[X_USRPT].n_value) == NULL) {
- X (void) fprintf(stderr, "%s: can't get kernel's usrpt\n", Pn);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(HPUX7) && defined(hp9000s800)
- X proc = (struct proc *)kp;
- X if ((ubase = (struct user *)Nl[X_UBASE].n_value) == NULL) {
- X (void) fprintf(stderr, "%s: can't get kernel's ubase\n", Pn);
- X exit(1);
- X }
- X if (Nl[X_NPIDS].n_value == NULL
- X || kread((off_t)Nl[X_NPIDS].n_value, (char *)&npids, sizeof(npids))) {
- X (void) fprintf(stderr, "%s: can't get kernel's npids\n", Pn);
- X exit(1);
- X }
- X#endif
- X
- X#if defined(_IBMR2)
- X if ((p = (struct procinfo *)malloc((size_t)PROCSIZE)) == NULL) {
- X (void) fprintf(stderr,
- X "%s: can't allocate space for 1 procinfo\n", Pn);
- X exit(1);
- X }
- X np = 0;
- X while (((np = getproc(p, np, PROCSIZE)) == -1) && errno == ENOSPC) {
- X np = p->p_pid + 10;
- X if ((p = (struct procinfo *)realloc((MALLOC_P *)p,
- X (size_t) (np * PROCSIZE))) == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for %ld procinfo's\n", Pn, np);
- X exit(1);
- X }
- X }
- X#endif
- X
- X#if defined(sun)
- X (void) kvm_setproc(Kd);
- X#endif
- X
- X/*
- X * Loop through the process table entries.
- X */
- X selflg = (Fnet || Fnfs || Funix || Npid || Nuid || Sfile) ? 0 : 1;
- X selpid = (Fnet || Fnfs || Funix || Nuid || Sfile) ? 0 : 1;
- X seluid = (Fnet || Fnfs || Funix || Sfile) ? 0 : 1;
- X
- X#if defined(DYNIX)
- X for (p = &ps, px = 0, u = &us; px < np; px++)
- X#endif
- X
- X#if defined(HPUX7)
- X for (p = &ps, px = 0, u = (struct user *)us; px < np; px++)
- X#endif
- X
- X#if defined(HPUX8)
- X for (p = &ps, px = 0, u = &us; px < np; px++)
- X#endif
- X
- X#if defined(_IBMR2)
- X for (; np; np--, p++)
- X#endif
- X
- X#if defined(NeXT)
- X for (np = procp, p = &ps; np; np = ps.p_nxt)
- X#endif
- X
- X#if defined(sun)
- X while ((p = kvm_nextproc(Kd)) != NULL)
- X#endif
- X
- X {
- X
- X#if defined(DYNIX)
- X if (kread((off_t)(kp + (long)(px * sizeof(struct proc))),
- X (char *)&ps, sizeof(ps)))
- X continue;
- X#endif
- X
- X#if defined(hpux)
- X Procaddr = kp + (long)(px * sizeof(struct proc));
- X if (kread((off_t)Procaddr, (char *)&ps, sizeof(ps)))
- X continue;
- X#endif
- X
- X#if defined(NeXT)
- X if (kread((off_t)np, (char *)&ps, sizeof(ps))) {
- X (void) fprintf(stderr,
- X "%s: can't read proc struct at %#x\n",
- X Pn, np);
- X exit(1);
- X }
- X#endif
- X
- X if (p->p_stat == 0 || p->p_stat == SZOMB)
- X continue;
- X fprint = selflg;
- X for (i = 0; fprint == 0 && i < Npid; i++) {
- X if (Spid[i] == p->p_pid)
- X fprint = 1;
- X }
- X if ( ! fprint && selpid)
- X continue;
- X
- X#if defined(NeXT)
- X /*
- X * Read the task associated with the process, and the user
- X * area assocated with the task.
- X */
- X if (kread((off_t) p->task, &t, sizeof(t)))
- X continue;
- X if ((struct proc *)t.proc != np)
- X continue;
- X if (kread((off_t) t.u_address, &ut, sizeof(ut)))
- X continue;
- X if ((struct proc *)ut.uu_procp != np)
- X continue;
- X u = &ut;
- X#endif
- X
- X/*
- X * Check for processes owned by specified user(s).
- X */
- X for (i = 0; fprint == 0 && i < Nuid; i++) {
- X if (Suid[i] == p->p_uid)
- X fprint = 1;
- X }
- X if ( ! fprint && seluid)
- X continue;
- X
- X#if defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(sun)
- X /*
- X * Get the user area associated with the process.
- X */
- X#endif
- X
- X#if defined(DYNIX)
- X if (getu(p, &us))
- X continue;
- X#endif
- X
- X#if defined(hpux)
- X if (getu(p, u))
- X continue;
- X#endif
- X
- X#if defined(_IBMR2)
- X u = &us;
- X if (getuser(p, PROCSIZE, u, U_SIZE) != 0)
- X continue;
- X#endif
- X
- X#if defined(sun)
- X if ((u = kvm_getu(Kd, p)) == NULL)
- X continue;
- X#endif
- X
- X /*
- X * Print information on the current directory.
- X */
- X
- X#if defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X if (u->u_cdir) {
- X#endif
- X
- X#if defined(HPUX8)
- X if (p->p_cdir) {
- X#endif
- X
- X Command = u->u_comm;
- X Fdev = 0;
- X Devch[0] = Iproto[0] = Type[0] = '\0';
- X /*
- X * The following line should be:
- X *
- X * (void) strcpy(Fd, " cwd");
- X *
- X * However, the 3.1.3 xlc compiler produces incorrect code
- X * for it when optimizing (-O). The 3.1.5 xlc compiles the
- X * strcpy() correctly.
- X */
- X (void) sprintf(Fd, "%4s", "cwd");
- X Fprint = fprint;
- X Inode = -1l;
- X Lock = ' ';
- X Namech[0] = '\0';
- X Pid = p->p_pid;
- X Size_def = 0;
- X Vtype = V_REG;
- X (void) printuid(p->p_uid);
- X
- X#if defined(DYNIX) || defined(HPUX7) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X printvnode((caddr_t)u->u_cdir);
- X#endif
- X
- X#if defined(HPUX8)
- X printvnode((caddr_t)p->p_cdir);
- X#endif
- X }
- X /*
- X * Loop through user's files.
- X */
- X
- X#if defined(DYNIX)
- X
- X#if !defined(DYNIX31)
- X /*
- X * Under DYNIX, the file pointers may be located in the user
- X * structure or in an extension to it. Determine which is the
- X * case and read the pointers.
- X */
- X
- X if (u->u_ofile_ext) {
- X if (kread((off_t)u->u_ofile_ext, (char *)&ofx, sizeof(ofx)))
- X nf = 0;
- X else {
- X nf = ofx.oe_nofile;
- X ui = (unsigned)(ofx.oe_nofile * sizeof(struct ofile));
- X if (ofp == NULL) {
- X xnf = nf;
- X if ((ofp = (struct ofile *)malloc(ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no malloc ofile space\n",
- X Pn);
- X exit(1);
- X }
- X } else if (nf > xnf) {
- X xnf = nf;
- X if ((ofp = (struct ofile *)realloc(
- X (MALLOC_P *)ofp, ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no realloc ofile space\n",
- X Pn);
- X exit(1);
- X }
- X }
- X if (kread((off_t)ofx.oe_ofile, (char *)ofp, (int)ui))
- X nf = 0;
- X else {
- X nf = ofx.oe_nofile;
- X uf = ofp;
- X }
- X }
- X } else {
- X nf = NOFILE;
- X uf = u->u_lofile;
- X }
- X#endif
- X
- X#if defined(DYNIX31)
- X /*
- X * Under DYNIX 3.1, the file pointers should be located in an extension
- X * to the user structure. Determine if is the case and read the
- X * pointers.
- X */
- X
- X if (u->u_ofile_tab) {
- X if (kread((off_t)u->u_ofile_tab, (char *)&oft, sizeof(oft)))
- X nf = 0;
- X else {
- X nf = oft.oft_nofile;
- X ui = (unsigned)(oft.oft_nofile * sizeof(struct ofile));
- X if (ofp == NULL) {
- X xnf = nf;
- X if ((ofp = (struct ofile *)malloc(ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no malloc ofile space\n",
- X Pn);
- X exit(1);
- X }
- X } else if (nf > xnf) {
- X xnf = nf;
- X if ((ofp = (struct ofile *)realloc(
- X (MALLOC_P *)ofp, ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no realloc ofile space\n",
- X Pn);
- X exit(1);
- X }
- X }
- X if (kread((off_t)oft.oft_ofile, (char *)ofp, (int)ui))
- X nf = 0;
- X else {
- X nf = oft.oft_nofile;
- X uf = ofp;
- X }
- X }
- X } else {
- X nf = NOFILE;
- X uf = u->u_lofileXXX;
- X }
- X#endif
- X
- X#endif
- X
- X#if defined(NeXT)
- X /*
- X * NeXTStep 2.0 and 2.1 file pointers come from a structure whose
- X * pointer is in the user area.
- X */
- X nf = ut.uu_ofile_cnt;
- X nb = (MALLOC_S) (sizeof(struct file) * nf);
- X if (uf == NULL) {
- X if ((uf = (struct file **)malloc(nb)) == NULL) {
- X (void) fprintf(stderr,
- X "%s: no file table space, process %d\n",
- X Pn, p->p_pid);
- X exit(1);
- X }
- X pnb = nb;
- X } else if (nb > pnb) {
- X if ((uf = (struct file **)realloc((MALLOC_P *)uf, nb))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: realloc file[]\n", Pn);
- X exit(1);
- X }
- X pnb = nb;
- X }
- X if (kread((off_t)ut.uu_ofile, (char *)uf, nb))
- X continue;
- X#endif
- X
- X#if defined(sun)
- X /*
- X * Under SunOS 4.1.1, the file pointers may be located in the
- X * user structure or in a separately allocated area. Determine
- X * which is the case and read the pointers.
- X */
- X if ((caddr_t)u->u_ofile
- X == ((caddr_t)&u->u_ofile_arr[0] - (caddr_t)&u
- X + (caddr_t)p->p_uarea)) {
- X nf = NOFILE_IN_U;
- X uf = &u->u_ofile_arr[0];
- X } else {
- X nf = u->u_lastfile + 1;
- X ui = nf * sizeof(struct file);
- X if (xuf == NULL) {
- X xnf = nf;
- X if ((xuf = (struct file **)malloc(ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: malloc file[]\n", Pn);
- X exit(1);
- X }
- X } else if (nf > xnf) {
- X xnf = nf;
- X if ((xuf = (struct file **)realloc(
- X (MALLOC_P *)xuf, ui))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: realloc file[]\n", Pn);
- X exit(1);
- X }
- X }
- X if (kread((off_t)u->u_ofile, (char *)xuf, (int)ui))
- X nf = 0;
- X uf = xuf;
- X }
- X#endif
- X
- X#if defined(DYNIX)
- X for (i = 0; i < nf; i++) {
- X if (uf[i].of_file)
- X#endif
- X
- X#if defined(HPUX7)
- X for (i = j = k = 0;; i++) {
- X if (j >= SFDCHUNK) {
- X
- X /*
- X * Get next HP-UX file pointer "chunk".
- X */
- X while (++k < NFDCHUNKS && u->u_ofilep[k] == NULL)
- X ;
- X if (k >= NFDCHUNKS)
- X break;
- X if (kread((off_t)u->u_ofilep[k],
- X (char *)&u->u_ofile,
- X sizeof(struct ofile_t)))
- X break;
- X j = 0;
- X }
- X j++;
- X if (u->u_ofile.ofile[j - 1])
- X#endif
- X
- X#if defined(HPUX8)
- X for (i = 0, j = SFDCHUNK;; i++) {
- X if (j >= SFDCHUNK) {
- X if (kread((off_t)p->p_ofilep, (char *)&ofp,
- X sizeof(ofp)))
- X {
- X (void) fprintf(stderr,
- X "%s: can't read ofilep from %#x\n",
- X Pn, ofp);
- X exit(1);
- X }
- X if (ofp == NULL)
- X break;
- X if (kread((off_t)ofp, (char *)&oft, sizeof(oft))) {
- X (void) fprintf(stderr,
- X "%s: can't read ofile_t from %#x\n",
- X Pn, ofp);
- X exit(1);
- X }
- X j = 0;
- X p->p_ofilep++;
- X }
- X j++;
- X if (oft.ofile[j - 1])
- X#endif
- X
- X#if defined(_IBMR2)
- X for (i = 0; i < u->u_maxofile; i++) {
- X if (u->u_ufd[i].fp)
- X#endif
- X
- X#if defined(NeXT) || defined(sun)
- X for (i = 0; i < nf; i++) {
- X if (uf[i])
- X#endif
- X {
- X
- X Command = u->u_comm;
- X Fdev = 0;
- X Fprint = fprint;
- X Devch[0] = Iproto[0] = Type[0] = '\0';
- X (void) sprintf(Fd, "%4d", i);
- X Inode = -1l;
- X Lock = ' ';
- X Namech[0] = '\0';
- X Pid = p->p_pid;
- X Size_def = 0;
- X Vtype = V_REG;
- X (void) printuid(p->p_uid);
- X
- X#if defined(DYNIX)
- X printfile(uf[i].of_file);
- X#endif
- X
- X#if defined(HPUX7)
- X printfile(u->u_ofile.ofile[j - 1]);
- X#endif
- X
- X#if defined(HPUX8)
- X printfile(oft.ofile[j - 1]);
- X#endif
- X
- X#if defined(_IBMR2)
- X printfile(u->u_ufd[i].fp);
- X#endif
- X
- X#if defined(NeXT)
- X printfile(uf[i]);
- X#endif
- X
- X#if defined(sun)
- X printfile(uf[i]);
- X#endif
- X }
- X }
- X }
- X for (sfp = Sfile; sfp; sfp = sfp->next) {
- X if (sfp->f == 0)
- X exit(1);
- X }
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(NeXT)
- X exit(0);
- X#endif
- X
- X#if defined(hpux) || defined(sun)
- X return(0);
- X#endif
- X
- X}
- X
- X
- X/*
- X * compdev() - compare device numbers
- X */
- X
- compdev(p1, p2)
- X struct dev **p1;
- X struct dev **p2;
- X{
- X if ((long)((*p1)->rdev) < (long)((*p2)->rdev))
- X return(-1);
- X if ((long)((*p1)->rdev) > (long)((*p2)->rdev))
- X return(1);
- X return(0);
- X}
- X
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X/*
- X * completevfs() - complete local vfs structure
- X */
- X
- void
- completevfs(vfs, dev)
- X struct l_vfs *vfs; /* local vfs structure pointer */
- X dev_t dev; /* inode/rnode device */
- X{
- X struct mounts *mp;
- X
- X for (mp = Mtab; mp; mp = mp->next) {
- X if (mp->dev == dev) {
- X
- X#if defined(DYNIX) || defined(hpux)
- X vfs->dev = mp->dev;
- X#endif
- X
- X vfs->dir = mp->dir;
- X vfs->fsname = mp->fsname;
- X return;
- X }
- X }
- X}
- X#endif
- X
- X
- X/*
- X * endnm() - locate end of Namech
- X */
- X
- char *
- endnm()
- X{
- X char *s;
- X
- X for (s = Namech; *s; s++)
- X ;
- X return(s);
- X}
- X
- X
- X/*
- X * entpid() - enter Process IDentifier for searching
- X */
- X
- entpid(p)
- X char *p; /* PID string pointer */
- X{
- X int i, pid;
- X char *s;
- X
- X for (s = p; *s;) {
- X /*
- X * Assemble Process IDentifier.
- X */
- X for (pid = 0; *s && *s != ','; *s++) {
- X if ( ! isascii(*s) || ! isdigit(*s)) {
- X (void) fprintf(stderr,
- X "%s: illegal PID specification: %s\n",
- X Pn, p);
- X return(1);
- X }
- X pid = (pid * 10) + *s - '0';
- X }
- X if (*s)
- X s++;
- X /*
- X * Avoid entering duplicates.
- X */
- X for (i = 0; i < Npid; i++) {
- X if (pid == Spid[i])
- X break;
- X }
- X if (i < Npid)
- X continue;
- X /*
- X * Allocate PID table space.
- X */
- X if (Npid >= Mxpid) {
- X Mxpid += PIDINCR;
- X if (Spid == NULL)
- X Spid = (int *)malloc((MALLOC_S)
- X (sizeof(int *) * Mxpid));
- X else
- X Spid = (int *)realloc((MALLOC_P *)Spid,
- X (MALLOC_S)(sizeof(int *) * Mxpid));
- X if (Spid == NULL) {
- X (void) fprintf(stderr, "%s: no space for PIDs",
- X Pn);
- X exit(1);
- X }
- X }
- X Spid[Npid++] = pid;
- X }
- X return(0);
- X}
- X
- X
- X/*
- X * entuid() - enter User Identifier for searching
- X */
- X
- entuid(u)
- X char *u; /* User IDentifier string pointer */
- X{
- X int err, i, n;
- X struct passwd *pw;
- X char *s;
- X char uid[LOGINML];
- X
- X for (err = 0, s = u; *s;) {
- X /*
- X * Assemble next User IDentifier.
- X */
- X for (i = n = 0; *s && *s != ','; i++, s++) {
- X if (i >= LOGINML-1) {
- X (void) fprintf(stderr,
- X "%s: illegal UID in %s\n", Pn, u);
- X return(1);
- X }
- X uid[i] = *s;
- X if (n < 0)
- X continue;
- X if (isascii(*s) && isdigit(*s))
- X n = (n * 10) + *s - '0';
- X else
- X n = -1;
- X }
- X if (*s)
- X s++;
- X if (n < 0) {
- X uid[i] = '\0';
- X if ((pw = getpwnam(uid)) == NULL) {
- X (void) fprintf(stderr,
- X "%s: can't get UID for %s\n",
- X Pn, uid);
- X err++;
- X continue;
- X } else
- X n = pw->pw_uid;
- X }
- X /*
- X * Avoid entering duplicates.
- X */
- X for (i = 0; i < Nuid; i++) {
- X if (n == Suid[i])
- X break;
- X }
- X if (i < Nuid)
- X continue;
- X /*
- X * Allocate space for User IDentifier.
- X */
- X if (Nuid >= Mxuid) {
- X Mxuid += UIDINCR;
- X if (Suid == NULL)
- X Suid = (int *)malloc((MALLOC_S)
- X (sizeof(int *) * Mxuid));
- X else
- X Suid = (int *)realloc((MALLOC_P *)Suid,
- X (MALLOC_S)(sizeof(int *) * Mxuid));
- X if (Suid == NULL) {
- X (void) fprintf(stderr, "%s: no space for UIDs",
- X Pn);
- X exit(1);
- X }
- X }
- X Suid[Nuid++] = n;
- X }
- X return(err);
- X}
- X
- X
- X#if defined(_IBMR2)
- X/*
- X * getchan() - get channel from file path name
- X */
- X
- int
- getchan(p)
- X char *p; /* file path name */
- X{
- X int ch;
- X char *s;
- X
- X if ((s = strrchr(p, '/')) == NULL)
- X return(-1);
- X if (*(++s) == '\0')
- X return(-1);
- X for (ch = 0; *s; s++) {
- X if ( ! isascii(*s) || ! isdigit(*s))
- X return(-1);
- X ch = (ch * 10) + *s - '0';
- X }
- X return(ch);
- X}
- X#endif
- X
- X
- X#if defined(DYNIX)
- X/*
- X * getu() - get DYNIX user area
- X */
- X
- getu(p, u)
- X struct proc *p; /* process area pointer */
- X struct user *u; /* user area destination */
- X{
- X off_t sp;
- X
- X if ((p->p_flag & SLOAD) == 0) {
- X sp = (off_t) dtob(p->p_swaddr);
- X if (lseek(Swap, sp, L_SET) != sp
- X || read(Swap, (char*)u, U_SIZE) != U_SIZE)
- X return(1);
- X } else {
- X if (kread((off_t)p->p_uarea, (char *)u, U_SIZE))
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X#if defined(hpux)
- X/*
- X * getu() - get HP-UX user area
- X */
- X
- getu(p, u)
- X struct proc *p; /* process area pointer */
- X
- X#if defined(HPUX7)
- X char *u; /* user area destination */
- X#endif
- X
- X#if defined(HPUX8)
- X struct user *u; /* user area destination */
- X#endif
- X
- X{
- X
- X#if defined(HPUX7)
- X long sw;
- X
- X#if defined(hp9000s300)
- X struct pte pte1, pte2;
- X off_t pte_off, pte_addr;
- X#endif
- X#endif
- X
- X#if defined(HPUX8)
- X char *c, *s;
- X int i;
- X struct pst_status ps;
- X#endif
- X
- X#if defined(HPUX7)
- X/*
- X * Read the HP-UX 7.x user area from the swap file or memory.
- X */
- X if ((p->p_flag & SLOAD) == 0) {
- X
- X /*
- X * If the process is not loaded, read the user area from the swap file.
- X */
- X sw = (long)p->p_swaddr;
- X
- X#if defined(hp9000s800)
- X sw += (long)ctod(btoc(STACKSIZE * NBPG));
- X#endif
- X
- X if (lseek(Swap, (off_t)dtob(sw), L_SET) == (off_t)-1
- X || read(Swap, u, U_SIZE) != U_SIZE)
- X return(1);
- X return(0);
- X }
- X
- X/*
- X * Read the HP-UX 7.x user area via the page table.
- X */
- X
- X#if defined(hp9000s300)
- X pte_off = (off_t) &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
- X if (kread(pte_off, (char *)&pte1, sizeof(pte1)))
- X return(1);
- X pte_addr = (off_t) (ctob(pte1.pg_pfnum + 1)
- X - ((UPAGES + FLOAT) * sizeof(pte2)));
- X if (lseek(Mem, pte_addr, L_SET) == (off_t)-1
- X || read(Mem, (char *)&pte2, sizeof(pte2)) != sizeof(pte2))
- X return(1);
- X if (lseek(Mem, (off_t)ctob(pte2.pg_pfnum), L_SET) == (off_t)-1
- X || read(Mem, u, sizeof(struct user)) != sizeof(struct user))
- X return(1);
- X#endif
- X
- X#if defined(hp9000s800)
- X if (kread((off_t)uvadd((struct proc *)Procaddr),u,sizeof(struct user)))
- X return(1);
- X#endif
- X#endif /* HPUX7 */
- X
- X#if defined(HPUX8)
- X/*
- X * Use the undocumented HP-UX 8.x pstat() syscall to read process status.
- X *
- X * (HP won't release pstat(2) documentation to customers who have paid for
- X * the inclusion of the syscall in HP-UX. You figure that one out.)
- X */
- X (void) bzero(u, U_SIZE);
- X if (pstat(PSTAT_PROC, &ps, sizeof(ps), 0, p->p_pid) != 1) {
- X (void) fprintf(stderr, "%s: can't pstat process %d: %s\n",
- X Pn, p->p_pid, sys_errlist[errno]);
- X return(1);
- X }
- X/*
- X * Scan the pst_cmd command buffer and skip to the last component of the
- X * first path name. Also skip any leading `-', signifying a login shell.
- X * Copy the result to u_comm[].
- X */
- X c = ps.pst_cmd;
- X ps.pst_cmd[PST_CLEN - 1] = '\0'; /* paranoia */
- X if (*c == '/') {
- X for (s = c; *s && *s != ' '; s++) {
- X if (*s == '/')
- X c = s + 1;
- X }
- X }
- X if (*c == '-')
- X c++;
- X for (i = 0; i < MAXCOMLEN; i++) {
- X if (*c == '\0' || *c == ' ' || *c == '/')
- X break;
- X u->u_comm[i] = *c++;
- X }
- X u->u_comm[i] = '\0';
- X/*
- X * Copy other process status values to the user area, as required.
- X */
- X#endif /* HPUX8 */
- X
- X return(0);
- X}
- X#endif
- X
- X
- X/*
- X * isfile() - is file selected for printing
- X */
- X
- isfile(d, ty, ch, i)
- X dev_t d; /* device */
- X enum vtype ty; /* vnode type */
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X int ch; /* dummy */
- X#endif
- X
- X#if defined(_IBMR2)
- X chan_t ch; /* gnode channel */
- X#endif
- X
- X long i; /* inode */
- X
- X/* ARGSUSED */
- X
- X{
- X int f;
- X struct sfile *s;
- X
- X for (f = 0, s = Sfile; s; s = s->next) {
- X
- X#if defined(_IBMR2)
- X /*
- X * Check for a regular AIX multiplexed file. Match the channel if
- X * it was supplied.
- X */
- X if (s->type && s->mode == S_IFCHR && d == s->dev
- X && ty == VMPC) {
- X if (s->ch < 0 || (s->ch >= 0 && ch == s->ch)) {
- X f = 1;
- X break;
- X }
- X }
- X#endif
- X
- X#if defined(sun)
- X /*
- X * Check for a Sun clone file.
- X */
- X if (Vtype == V_STREAM && major(s->dev) == CLONEMAJ
- X && major(d) == minor(s->dev)) {
- X f = 1;
- X break;
- X }
- X#endif
- X
- X /*
- X * Check for a regular file or directory -- the device and
- X * inode numbers must match.
- X */
- X if (s->type) {
- X if (d == s->dev && (ino_t)i == s->i) {
- X f = 1;
- X break;
- X }
- X continue;
- X }
- X /*
- X * Check for a file system match.
- X * Try to avoid matching VCHR files to non-character devices.
- X */
- X if (d == s->dev) {
- X if ( ! (ty == VCHR && s->mode != S_IFCHR)) {
- X f = 1;
- X break;
- X }
- X }
- X }
- X/*
- X * Convert the name if a match occurred.
- X */
- X if (f) {
- X (void) strcpy(Namech, s->name);
- X
- X#if defined(_IBMR2)
- X if (ty == VMPC && s->ch < 0)
- X (void) sprintf(endnm(), "/%d", ch);
- X#endif
- X
- X if (s->devnm)
- X (void) sprintf(endnm(), " (%s)", s->devnm);
- X s->f = 1;
- X return(1);
- X }
- X return(0);
- X}
- X
- X
- X#if defined(_IBMR2)
- X/*
- X * isglocked() - is a gnode locked
- X */
- X
- char
- isglocked(ga)
- X struct gnode *ga; /* local gnode address */
- X{
- X
- X struct filock f;
- X off_t l;
- X
- X if (ga->gn_filocks == NULL)
- X return(' ');
- X if (kread((off_t)ga->gn_filocks, &f, sizeof(f)))
- X return(' ');
- X if (f.set.l_whence == 0 && f.set.l_start == 0 && f.set.l_len == MAXEND)
- X l = 1;
- X else
- X l = 0;
- X switch (f.set.l_type & (F_RDLCK | F_WRLCK)) {
- X
- X case F_RDLCK:
- X return((l) ? 'R' : 'r');
- X case F_WRLCK:
- X return((l) ? 'W' : 'w');
- X case (F_RDLCK + F_WRLCK):
- X return('*');
- X }
- X return(' ');
- X}
- X#endif
- X
- X
- X/*
- X * kread() - read from kernel memory
- X */
- X
- int
- kread(addr, buf, len)
- X off_t addr; /* kernel memory address */
- X char *buf; /* buffer to receive data */
- X int len; /* length to read */
- X{
- X int br;
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(hpux) || defined(NeXT)
- X if (lseek(Kmem, addr, L_SET) == (off_t)-1)
- X return(-1);
- X br = read(Kmem, buf, len);
- X#endif
- X
- X#if defined(sun)
- X br = kvm_read(Kd, (u_long)addr, buf, len);
- X#endif
- X
- X return((br == len) ? 0 : 1);
- X}
- X
- X
- X/*
- X * printchdevname() - print character device name
- X */
- X
- void
- printchdevname(rdev, chan)
- X dev_t rdev; /* device */
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X int chan; /* dummy */
- X#endif
- X
- X#if defined(_IBMR2)
- X chan_t chan; /* channel */
- X#endif
- X
- X/* ARGSUSED */
- X
- X{
- X
- X#if defined(sun)
- X struct clone *c;
- X#endif
- X
- X int low, hi, mid;
- X struct dev *dp;
- X
- X
- X#if defined(sun)
- X/*
- X * If this is a SunOS stream vnode, search for the clone parent.
- X */
- X if (Vtype == V_STREAM && Clone) {
- X for (c = Clone; c; c = c->next) {
- X dp = c->dp;
- X if (major(rdev) == minor(dp->rdev))
- X goto found_device;
- X }
- X }
- X#endif
- X
- X low = mid = 0;
- X hi = Ndev - 1;
- X while (low <= hi) {
- X mid = (low + hi) / 2;
- X dp = Sdev[mid];
- X if ((long)rdev < (long)dp->rdev)
- X hi = mid - 1;
- X else if ((long)rdev > (long)dp->rdev)
- X low = mid + 1;
- X else {
- X
- X#if defined(sun)
- X
- found_device:
- X
- X#endif
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X (void) strcpy(Namech, dp->name);
- X#endif
- X
- X#if defined(_IBMR2)
- X if (chan < 0)
- X (void) strcpy(Namech, dp->name);
- X else
- X (void) sprintf(Namech, "%s/%d", dp->name,
- X chan);
- X#endif
- X
- X return;
- X }
- X }
- X (void) strcpy(Namech, "name unknown");
- X}
- X
- X
- X#if defined(DTYPE_GNODE)
- X/*
- X * printdevice() - print device file
- X */
- X
- printdevice(va)
- X caddr_t va; /* vnode's kernel address */
- X{
- X struct vnode v;
- X
- X if (readvnode(va, &v)) {
- X printline();
- X return;
- X }
- X (void) strcpy(Type, "dev");
- X printline();
- X}
- X#endif
- X
- X
- X/*
- X * printfile() - print file information
- X */
- X
- void
- printfile(fp)
- X struct file *fp; /* kernel file table address */
- X{
- X struct file f;
- X
- X if (kread((off_t) fp, (char *) &f, sizeof(f))) {
- X (void) sprintf(Namech, "can't read file struct from %#x", fp);
- X } else {
- X if (f.f_count) {
- X switch (f.f_type) {
- X
- X case DTYPE_VNODE:
- X printvnode(f.f_data);
- X break;
- X
- X case DTYPE_SOCKET:
- X printsocket((caddr_t)f.f_data);
- X break;
- X
- X#if defined(DTYPE_GNODE)
- X case DTYPE_GNODE:
- X printdevice(f.f_data);
- X break;
- X#endif
- X
- X default:
- X (void) sprintf(Namech,
- X "unknown file struct type %#x at %#x\n",
- X f.f_type, fp);
- X printline();
- X }
- X return;
- X }
- X }
- X return;
- X}
- X
- X
- X/*
- X * printinaddr() - print Internet address
- X */
- X
- void
- printinaddr(ia, p)
- X struct in_addr *ia; /* Internet address */
- X u_short p; /* port */
- X{
- X unsigned char *u;
- X
- X if (ia->s_addr == INADDR_ANY) {
- X (void) sprintf(endnm(), "*:%d", p);
- X return;
- X }
- X u = (unsigned char *) ia;
- X (void) sprintf(endnm(), "%u.%u.%u.%u:%u", u[0], u[1], u[2], u[3], p);
- X}
- X
- X
- X/*
- X * printiproto() - print Internet protocol name
- X */
- X
- void
- printiproto(p)
- X int p; /* protocol number */
- X{
- X int i;
- X static int m = -1;
- X char *s;
- X
- X switch(p) {
- X
- X#if defined(IPPROTO_TCP)
- X case IPPROTO_TCP:
- X s = "TCP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_UDP)
- X case IPPROTO_UDP:
- X s = "UDP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_IP)
- X case IPPROTO_IP:
- X s = "IP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_ICMP)
- X case IPPROTO_ICMP:
- X s = "ICMP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_IGMP)
- X case IPPROTO_IGMP:
- X s = "IGMP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_GGP)
- X case IPPROTO_GGP:
- X s = "GGP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_EGP)
- X case IPPROTO_EGP:
- X s = "EGP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_PUP)
- X case IPPROTO_PUP:
- X s = "PUP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_IDP)
- X case IPPROTO_IDP:
- X s = "IDP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_ND)
- X case IPPROTO_ND:
- X s = "ND";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_RAW)
- X case IPPROTO_RAW:
- X s = "RAW";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_HELLO)
- X case IPPROTO_HELLO:
- X s = "HELLO";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_PXP)
- X case IPPROTO_PXP:
- X s = "PXP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_RAWIP)
- X case IPPROTO_RAWIP:
- X s = "RAWIP";
- X break;
- X#endif
- X
- X#if defined(IPPROTO_RAWIF)
- X case IPPROTO_RAWIF:
- X s = "RAWIF";
- X break;
- X#endif
- X
- X default:
- X s = NULL;
- X }
- X if (s)
- X (void) sprintf(Iproto, "%*.*s", IPROTOL, IPROTOL, s);
- X else {
- X if (m < 0) {
- X for (i = 0, m = 1; i < IPROTOL-1; i++)
- X m *= 10;
- X }
- X (void) sprintf(Iproto, "%d?", p % m);
- X }
- X}
- X
- X
- X/*
- X * printline() - print output line
- X */
- X
- void
- printline()
- X{
- X if (Fprint == 0)
- X return;
- X if (Fterse) {
- X (void) printf("%d\n", Pid);
- X return;
- X }
- X if (Hdr == 0) {
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X (void) printf("COMMAND PID USER FD TYPE DEVICE");
- X#endif
- X
- X#if defined(hpux)
- X (void) printf("COMMAND PID USER FD TYPE DEVICE");
- X#endif
- X
- X if (Fsize)
- X (void) printf(" SIZE");
- X (void)printf(" INODE/NAME\n");
- X }
- X Hdr++;
- X (void) printf("%-9.9s%6d %8s %4s%c %4.4s ",
- X Command ? Command : "",
- X Pid,
- X User,
- X Fd,
- X Lock,
- X Type
- X );
- X if (Fdev)
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X (void) printf(" %4d,%4d ", major(Dev), minor(Dev));
- X#endif
- X
- X#if defined(hpux)
- X (void) printf("%3d,0x%06x ", major(Dev), minor(Dev));
- X#endif
- X
- X else {
- X if (Devch[0])
- X
- X#if defined(DYNIX) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X (void) printf("%s ", Devch);
- X else
- X (void) printf(" ");
- X#endif
- X
- X#if defined(hpux)
- X (void) printf(" %s ", Devch);
- X else
- X (void) printf(" ");
- X#endif
- X
- X }
- X if (Fsize) {
- X if (Size_def)
- X (void) printf("%8d ", Size);
- X else
- X (void) printf(" ");
- X }
- X if (Inode >= 0)
- X (void) printf("%7ld ", Inode);
- X else if (Inode == -2l) {
- X if (Iproto[0] == '\0')
- X (void) printf("%7s ", "");
- X else
- X (void) printf("%7.7s ", Iproto);
- X }
- X (void) printf("%s\n", Namech);
- X}
- X
- X
- X/*
- X * printsocket() - print socket
- X */
- X
- void
- printsocket(sa)
- X caddr_t sa; /* socket address in kernel */
- X{
- X int fam;
- X
- X#if defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X struct domain d;
- X#endif
- X
- X#if defined(_IBMR2)
- X struct gnode g;
- X struct inode i;
- X int is = 0;
- X struct vnode v;
- X#endif
- X
- X struct inpcb inp;
- X struct mbuf mb;
- X struct protosw p;
- X struct socket s;
- X struct sockaddr_un *ua;
- X struct unpcb uc, unp;
- X
- X (void) strcpy(Type, "sock");
- X Inode = -2l;
- X if (sa == NULL) {
- X (void) sprintf(Namech, "no socket address");
- X printline();
- X return;
- X }
- X if (kread((off_t) sa, (char *) &s, sizeof(s))) {
- X (void) sprintf(Namech, "can't read socket struct from %#x",
- X sa);
- X printline();
- X return;
- X }
- X if (s.so_proto == NULL
- X || kread((off_t) s.so_proto, (char *) &p, sizeof(p))) {
- X (void) strcpy(Namech, "no protocol switch");
- X printline();
- X return;
- X }
- X
- X#if defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X if (kread((off_t) p.pr_domain, (char *) &d, sizeof(d))) {
- X (void) sprintf(Namech, "can't read domain struct from %#x",
- X p.pr_domain);
- X printline();
- X return;
- X }
- X#endif
- X
- X/*
- X * Process socket by the associated domain family.
- X */
- X
- X#if defined(DYNIX) || defined(HPUX8) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X switch ((fam = d.dom_family))
- X#endif
- X
- X#if defined(HPUX7)
- X switch ((fam = p.pr_family))
- X#endif
- X
- X {
- X case AF_INET:
- X if (Fnet)
- X Fprint = 1;
- X (void) strcpy(Type, "inet");
- X /*
- X * Read Internet protocol control block.
- X */
- X if (s.so_pcb == NULL
- X || kread((off_t) s.so_pcb, (char *) &inp, sizeof(inp)))
- X return;
- X if ((struct socket *)sa != inp.inp_socket)
- X return;
- X printiproto(p.pr_protocol);
- X (void) sprintf(Devch, "0x%08x",
- X (inp.inp_ppcb == NULL) ? s.so_pcb
- X : inp.inp_ppcb);
- X
- X#if defined(DYNIX)
- X printinaddr(&inp.inp_laddr, ntohs(inp.inp_lport));
- X#endif
- X
- X#if defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X printinaddr(&inp.inp_laddr, inp.inp_lport);
- X#endif
- X
- X if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) {
- X (void) strcat(endnm(), "->");
- X
- X#if defined(DYNIX)
- X printinaddr(&inp.inp_faddr, ntohs(inp.inp_fport));
- X#endif
- X
- X#if defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- X printinaddr(&inp.inp_faddr, inp.inp_fport);
- X#endif
- X
- X }
- X break;
- X
- X case AF_UNIX:
- X if (Funix)
- X Fprint = 1;
- X (void) strcpy(Type, "unix");
- X /*
- X * Read Unix protocol control block and the Unix address structure.
- X */
- X
- X (void) sprintf(Devch, "0x%08x", sa);
- X if (kread((off_t) s.so_pcb, (char *) &unp, sizeof(unp))) {
- X (void) sprintf(Namech, "can't read unpcb at %#x",
- X s.so_pcb);
- X break;
- X }
- X if ((struct socket *)sa != unp.unp_socket) {
- X (void) sprintf(Namech, "unp_socket (%#x) mismatch",
- X unp.unp_socket);
- X break;
- X }
- X if (unp.unp_addr) {
- X if (kread((off_t) unp.unp_addr, (char *) &mb, sizeof(mb))) {
- X (void) sprintf(Namech,
- X "can't read unp_addr at %#x",
- X unp.unp_addr);
- X break;
- X }
- X ua = (struct sockaddr_un *)(((char *)&mb) + mb.m_off);
- X } else {
- X ua = (struct sockaddr_un *)&mb;
- X (void) bzero((char *)ua, sizeof(struct sockaddr_un));
- X ua->sun_family = AF_UNSPEC;
- X }
- X /*
- X * Print information on Unix socket that has no address bound
- X * to it, although it may be connected to another Unix domain
- X * socket as a pipe.
- X */
- X if (ua->sun_family != AF_UNIX) {
- X if (ua->sun_family == AF_UNSPEC) {
- X if (unp.unp_conn) {
- X if (kread((off_t) unp.unp_conn,
- X (char *) &uc, sizeof(uc))) {
- X (void) sprintf(Namech,
- X "can't read unp_conn at %#x",
- X unp.unp_conn);
- X } else {
- X (void) sprintf(Namech,
- X "->0x%08x", uc.unp_socket);
- X }
- X } else
- X (void) strcpy(Namech, "->(none)");
- X } else
- X (void) sprintf(Namech,
- X "unknown sun_family (%d)",
- X ua->sun_family);
- X break;
- X }
- X
- X#if defined(_IBMR2)
- X /*
- X * Read any associated vnode and then read its gnode and inode.
- X */
- X g.gn_type = VSOCK;
- X if (unp.unp_vnode && readvnode(unp.unp_vnode, &v) == 0) {
- X if (v.v_gnode && readgnode(v.v_gnode, &g) == 0) {
- X Lock = isglocked(&g);
- X if (g.gn_type == VSOCK && g.gn_data
- X && readinode(g.gn_data, &i) == 0)
- X is = 1;
- X }
- X }
- X /*
- X * Print Unix socket information.
- X */
- X if (is) {
- X Dev = i.i_dev;
- X Fdev = 1;
- X Devch[0] = '\0';
- X Inode = (long)i.i_number;
- X }
- X#endif
- X
- X (void) sprintf(Namech, "%.*s",
- X mb.m_len - sizeof(ua->sun_family),
- X ua->sun_path[0] ? ua->sun_path : "no address");
- X break;
- X
- X default:
- X (void) sprintf(Namech, "unknown family %#x", fam);
- X }
- X printline();
- X}
- X
- X
- X/*
- X * printuid() - print User ID or login name
- X */
- X
- void
- printuid(u)
- X uid_t u; /* User ID number */
- X{
- X static int p = 0;
- X static uid_t pu;
- X struct passwd *pw;
- X
- X if (p && u == pu)
- X return;
- X p = 1;
- X pu = u;
- X if (Futol && (pw = getpwuid(u)) != NULL)
- X (void) sprintf(User, "%*.*s", USERPRTL, USERPRTL, pw->pw_name);
- X else
- X (void) sprintf(User, "%*d", USERPRTL, u);
- X}
- X
- X
- X/*
- X * printvnode() - print vnode
- X */
- X
- void
- printvnode(va)
- X caddr_t va; /* vnode kernel space address */
- X{
- X
- X dev_t dev;
- X struct inode i;
- X int prdev;
- X struct rnode r;
- X char *ty;
- X enum vtype type;
- X struct vnode v;
- X struct l_vfs *vfs;
- X
- X#if defined(NeXT)
- X struct vnode rv;
- X struct snode s;
- X#endif
- X
- X#if defined(_IBMR2)
- X struct cdrnode c;
- X struct gnode g;
- X#endif
- X
- X#if defined(sun)
- X struct fifonode f;
- X struct vnode rv;
- X struct snode s;
- X struct tmpnode t;
- X#endif
- X
- X/*
- X * Read the vnode.
- X */
- X if (readvnode((caddr_t)va, &v)) {
- X printline();
- X return;
- X }
- X
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X/*
- X * Determine the DYNIX, HP-UX, NeXT and SunOS vnode type.
- X */
- X if ((unsigned long)v.v_op == Nl[X_NFS_OPS].n_value)
- X Vtype = V_NFS;
- X
- X#if defined(sun)
- X else if ((unsigned long)v.v_op == Nl[X_TMP_OPS].n_value)
- X Vtype = V_TMP;
- X#endif
- X
- X else if (v.v_type == VFIFO)
- X Vtype = V_FIFO;
- X
- X#if defined(sun)
- X else if (v.v_type == VCHR && !v.v_vfsp && v.v_stream)
- X Vtype = V_STREAM;
- X#endif
- X
- X/*
- X * Determine the DYNIX, HP-UX, NeXT or SunOS lock type.
- X */
- X if (v.v_shlockc || v.v_exlockc) {
- X if (v.v_shlockc && v.v_exlockc)
- X Lock = '*';
- X else if (v.v_shlockc)
- X Lock = 'R';
- X else
- X Lock = 'W';
- X }
- X#endif
- X
- X/*
- X * Read the virtual file system structure.
- X */
- X if ((vfs = readvfs(v.v_vfsp)) == NULL) {
- X (void) sprintf(Namech, "can't read vfs for %#x at %#x", v,
- X v.v_vfsp);
- X printline();
- X return;
- X }
- X
- X#if defined(_IBMR2)
- X/*
- X * Determine the AIX vnode type.
- X */
- X if (vfs->vmt_flags & MNT_REMOTE)
- X Vtype = V_NFS;
- X/*
- X * Read the AIX gnode and the associated inode or rnode.
- X */
- X
- X if (v.v_gnode) {
- X if (readgnode(v.v_gnode, &g)) {
- X printline();
- X return;
- X }
- X } else {
- X (void) sprintf(Namech, "vnode at %#x has no gnode\n", va);
- X printline();
- X return;
- X }
- X Lock = isglocked(&g);
- X if (Vtype == V_NFS) {
- X if (g.gn_data == NULL || readrnode(g.gn_data, &r)) {
- X (void) sprintf(Namech,
- X "remote gnode at %#x has no rnode", v.v_gnode);
- X printline();
- X return;
- X }
- X } else {
- X if (vfs->vmt_gfstype == MNT_CDROM) {
- X if (g.gn_data == NULL || readcdrnode(g.gn_data, &c)) {
- X (void) sprintf(Namech,
- X "gnode at %#x has no cdrnode",
- X v.v_gnode);
- X printline();
- X return;
- X }
- X i.i_number = c.cn_inumber;
- X i.i_size = (off_t)c.cn_size;
- X } else if (g.gn_data == NULL || readinode(g.gn_data, &i)) {
- X (void) sprintf(Namech, "gnode at %#x has no inode",
- X v.v_gnode);
- X printline();
- X return;
- X }
- X }
- X#endif
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X/*
- X * Read the DYNIX, HP-UX, NeXT or SunOS fifonode, inode, rnode, snode or
- X * tmpnode.
- X */
- X switch (Vtype) {
- X case V_NFS:
- X if (!v.v_data || readrnode((caddr_t)v.v_data, &r)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read rnode (%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X break;
- X
- X#if defined(sun)
- X case V_FIFO:
- X
- X /*
- X * A Sun FIFO's vnode is linked to a fifonode. The s_realvp
- X * pointer of the snode contained in the fifonode points to
- X * a vnode that points to the inode. (Whew!)
- X */
- X if (!v.v_data || readfifonode(v.v_data, &f)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read fifonode (%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X if (f.fn_snode.s_realvp) {
- X if (readvnode((caddr_t)f.fn_snode.s_realvp, &rv)) {
- X (void) sprintf(Namech,
- X "fifonode at %#x: can't read real vnode (%#x)",
- X v.v_data, f.fn_snode.s_realvp);
- X printline();
- X return;
- X }
- X if (!rv.v_data || readinode(rv.v_data, &i)) {
- X (void) sprintf(Namech,
- X "fifonode at %#x: can't read inode (%#x)",
- X v.v_data, rv.v_data);
- X printline();
- X return;
- X }
- X } else {
- X printline();
- X return;
- X }
- X break;
- X case V_STREAM:
- X if (!v.v_data || readsnode((caddr_t)v.v_data, &s)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read snode (%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X break;
- X case V_TMP:
- X if (!v.v_data || readtnode((caddr_t)v.v_data, &t)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read tnode (%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X break;
- X#endif
- X
- X case V_REG:
- X default:
- X
- X#if defined(NeXT) || defined(sun)
- X /*
- X * NeXT and Sun VCHR vnodes point to an snode. The snode's s_realvp
- X * usually points to a real vnode, which points to an inode.
- X */
- X if (v.v_type == VCHR) {
- X if (!v.v_data || readsnode(v.v_data, &s)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read snode(%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X if (s.s_realvp) {
- X if (readvnode((caddr_t)s.s_realvp, &rv)) {
- X (void) sprintf(Namech,
- X "snode at %#x: can't read real vnode (%#x)",
- X v.v_data, s.s_realvp);
- X printline();
- X return;
- X }
- X if (!rv.v_data || readinode(rv.v_data, &i)) {
- X (void) sprintf(Namech,
- X "snode at %#x: can't read inode (%#x)",
- X v.v_data, rv.v_data);
- X printline();
- X return;
- X }
- X } else
- X (void) bzero((char *)&i, sizeof(i));
- X break;
- X }
- X#endif
- X
- X if (!v.v_data || readinode(v.v_data, &i)) {
- X (void) sprintf(Namech,
- X "vnode at %#x: can't read inode (%#x)",
- X va, v.v_data);
- X printline();
- X return;
- X }
- X }
- X#endif
- X
- X/*
- X * Get device and type for printing.
- X */
- X
- X#if defined(DYNIX)
- X switch(Vtype) {
- X case V_NFS:
- X
- X /*
- X * Neither the rnode nor the vnode under DYNIX 3.0.12 contains the
- X * correct device number, so it's reclaimed (if possible) from the
- X * local, virtual file system table entry (put there by completevfs()
- X * from information placed in Mtab by readmnt()).
- X */
- X dev = vfs->dev;
- X break;
- X default:
- X dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
- X }
- X type = v.v_type;
- X if (vfs->dir == NULL)
- X (void) completevfs(vfs, dev);
- X#endif
- X
- X#if defined(hpux)
- X if (Vtype == V_NFS)
- X dev = vfs->dev;
- X else
- X dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
- X type = v.v_type;
- X#endif
- X
- X#if defined(_IBMR2)
- X if (Vtype == V_NFS)
- X dev = vfs->dev;
- X else
- X dev = g.gn_rdev;
- X type = g.gn_type;
- X#endif
- X
- X#if defined(NeXT)
- X switch (Vtype) {
- X case V_NFS:
- X dev = r.r_attr.va_fsid;
- X if (dev & 0x8000)
- X dev |= 0xff00;
- X break;
- X case V_REG:
- X dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
- X }
- X type = v.v_type;
- X if (vfs->dir == NULL)
- X (void) completevfs(vfs, dev);
- X#endif
- X
- X#if defined(sun)
- X switch (Vtype) {
- X case V_NFS:
- X dev = r.r_attr.va_fsid;
- X break;
- X case V_STREAM:
- X dev = s.s_dev;
- X break;
- X case V_TMP:
- X dev = t.tn_attr.va_fsid;
- X break;
- X default:
- X dev = (v.v_type == VCHR) ? v.v_rdev : i.i_dev;
- X }
- X type = v.v_type;
- X if (vfs->dir == NULL)
- X (void) completevfs(vfs, dev);
- X#endif
- X
- X/*
- X * Obtain the inode number.
- X */
- X
- X#if defined(DYNIX)
- X switch (Vtype) {
- X case V_NFS:
- X Inode = (long)r.r_nfsattr.na_nodeid;
- X break;
- X case V_FIFO:
- X case V_REG:
- X Inode = (long)i.i_number;
- X }
- X#endif
- X
- X#if defined(hpux)
- X switch (Vtype) {
- X case V_NFS:
- X Inode = (long)r.r_nfsattr.na_nodeid;
- X break;
- X case V_FIFO:
- X case V_REG:
- X Inode = (long)i.i_number;
- X }
- X#endif
- X
- X#if defined(_IBMR2)
- X Inode = (long)(Vtype == V_NFS) ? r.r_attr.va_serialno : i.i_number;
- X#endif
- X
- X#if defined(NeXT)
- X switch(Vtype) {
- X case V_NFS:
- X Inode = (long)r.r_attr.va_nodeid;
- X break;
- X case V_REG:
- X Inode = (long)i.i_number;
- X }
- X#endif
- X
- X#if defined(sun)
- X switch (Vtype) {
- X case V_NFS:
- X Inode = (long)r.r_attr.va_nodeid;
- X break;
- X case V_FIFO:
- X case V_REG:
- X Inode = (long)i.i_number;
- X break;
- X case V_TMP:
- X Inode = (long)t.tn_attr.va_nodeid;
- X break;
- X case V_STREAM:
- X Inode = -2l;
- X }
- X#endif
- X
- X/*
- X * Obtain the file size.
- X */
- X switch (Vtype) {
- X case V_NFS:
- X
- X#if defined(DYNIX) || defined(hpux)
- X Size = r.r_nfsattr.na_size;
- X#endif
- X
- X#if defined(_IBMR2) || defined(NeXT) || defined(sun)
- X Size = r.r_attr.va_size;
- X#endif
- X
- X Size_def = 1;
- X break;
- X case V_REG:
- X Size = i.i_size;
- X Size_def = 1;
- X }
- X
- X/*
- X * Format the name characters.
- X */
- X if (Vtype == V_NFS && Fnfs)
- X Fprint = 1;
- X (void) sprintf(Namech, "%s (%s)",
- X (vfs->dir) ? vfs->dir : "",
- X (vfs->fsname) ? vfs->fsname : "");
- X/*
- X * Test for specified file.
- X */
- X prdev = 1;
- X if (Sfile && Fprint == 0) {
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X Fprint = isfile(dev, type, 0, Inode);
- X#endif
- X
- X#if defined(_IBMR2)
- X Fprint = isfile(dev, type, g.gn_chan, Inode);
- X#endif
- X
- X if (Fprint == 0)
- X return;
- X prdev = 0;
- X }
- X/*
- X * Format the vnode type, and possibly the device name.
- X */
- X switch (type) {
- X
- X case VNON:
- X ty ="VNON";
- X break;
- X case VREG:
- X case VDIR:
- X ty = (type == VREG) ? "VREG" : "VDIR";
- X Fdev = 1;
- X Dev = dev;
- X break;
- X case VBLK:
- X ty = "VBLK";
- X break;
- X case VCHR:
- X Dev = dev;
- X Fdev = 1;
- X if (prdev)
- X (void) printchdevname(Dev, -1);
- X ty = "VCHR";
- X break;
- X case VLNK:
- X ty = "VLNK";
- X break;
- X case VSOCK:
- X ty = "SOCK";
- X break;
- X case VBAD:
- X ty = "VBAD";
- X break;
- X case VFIFO:
- X Dev = dev;
- X Fdev = 1;
- X ty = "FIFO";
- X break;
- X
- X#if defined(_IBMR2)
- X case VMPC:
- X Dev = g.gn_rdev;
- X Fdev = 1;
- X Inode = -2l;
- X if (prdev)
- X (void) printchdevname(g.gn_rdev, g.gn_chan);
- X ty = "VMPC";
- X break;
- X#endif
- X
- X default:
- X (void) sprintf(Type, "%4d", type);
- X (void) strcpy(Namech, "unknown type");
- X ty = NULL;
- X }
- X if (ty)
- X (void) strcpy(Type, ty);
- X/*
- X * Print the line (at last) if printing has been selected.
- X */
- X printline();
- X}
- X
- X
- X#if defined(_IBMR2)
- X/*
- X * readcdrnode() - read CD-ROM node
- X */
- X
- int
- readcdrnode(ca, c)
- X caddr_t ca; /* cdrnode kernel address */
- X struct cdrnode *c; /* cdrnode buffer */
- X{
- X if (kread((off_t)ca, (char *)c, sizeof(struct cdrnode))) {
- X (void) sprintf(Namech, "can't read cdrnode at %#x", ca);
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X/*
- X * readdev() - read names, modes and device types of everything in /dev
- X */
- X
- void
- readdev()
- X{
- X
- X DIR *dfp;
- X int dn = 0;
- X char **dstk = NULL;
- X int dx = 0;
- X int err = 0;
- X int i = 0;
- X MALLOC_S nl;
- X char path[MAXNAMLEN+1];
- X int pl;
- X struct stat sb;
- X
- X#if defined(DYNIX) || defined(NeXT)
- X struct direct *dp;
- X#endif
- X
- X#if defined(hpux) || defined(_IBMR2) || defined(sun)
- X struct dirent *dp;
- X#endif
- X
- X#if defined(sun)
- X struct clone *c;
- X#endif
- X
- X (void) stkdir(&dstk, &dn, &dx, "/dev");
- X/*
- X * Unstack the next /dev or /dev/<subdirectory> directory.
- X */
- X while (--dx >= 0) {
- X (void) strcpy(path, dstk[dx]);
- X if ((dfp = opendir(path)) == NULL) {
- X if (Fdevmsg)
- X (void) fprintf(stderr, "%s: can't open %s\n",
- X Pn, path);
- X continue;
- X }
- X (void) strcat(path, "/");
- X pl = strlen(path);
- X (void) free((FREE_P *)dstk[dx]);
- X dstk[dx] = NULL;
- X /*
- X * Scan the directory.
- X */
- X for (dp = readdir(dfp); dp; dp = readdir(dfp)) {
- X if (dp->d_ino == 0 || dp->d_name[0] == '.')
- X continue;
- X /*
- X * Form the full path name and get its status.
- X */
- X if ((nl = pl + dp->d_namlen) >= sizeof(path)) {
- X (void) fprintf(stderr,
- X "%s: /dev entry name too long: %s\n",
- X Pn, dp->d_name);
- X exit(1);
- X }
- X (void) strncpy(&path[pl], dp->d_name,
- X (STRNCPY_L)dp->d_namlen);
- X path[nl++] = '\0';
- X if (lstat(path, &sb) != 0) {
- X (void) fprintf(stderr,
- X "%s: can't lstat %s: %s\n",
- X Pn, path, sys_errlist[errno]);
- X err++;
- X continue;
- X }
- X /*
- X * If it's a subdirectory, stack its name for later
- X * processing.
- X */
- X if ((sb.st_mode & S_IFMT) == S_IFDIR) {
- X (void) stkdir(&dstk, &dn, &dx, path);
- X continue;
- X }
- X /*
- X * Skip all but character devices.
- X */
- X if ((sb.st_mode & S_IFMT) != S_IFCHR)
- X continue;
- X /*
- X * Make room for another Devtp[] entry.
- X */
- X if (i >= Ndev) {
- X Ndev += DEVINCR;
- X if (Devtp == NULL)
- X Devtp = (struct dev *)malloc(
- X (MALLOC_S)(sizeof(struct dev) * Ndev));
- X else
- X Devtp = (struct dev *)realloc(
- X (MALLOC_P *)Devtp,
- X (MALLOC_S)(sizeof(struct dev)*Ndev));
- X if (Devtp == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for devices\n",
- X Pn);
- X exit(1);
- X }
- X }
- X /*
- X * Store the name and device number in the Devtp[] entry.
- X */
- X Devtp[i].rdev = sb.st_rdev;
- X if ((Devtp[i].name = (char *)malloc(nl)) == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for /dev/%s\n",
- X Pn, dp->d_name);
- X exit(1);
- X }
- X (void) strcpy(Devtp[i].name, path);
- X
- X#if defined(sun)
- X /*
- X * Save the locations of the SunOS clone devices.
- X */
- X if (major(Devtp[i].rdev) == CLONEMAJ) {
- X if ((c =
- X (struct clone *)malloc(sizeof(struct clone)))
- X == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for clone\n", Pn);
- X exit(1);
- X }
- X c->dp = &Devtp[i];
- X c->next = Clone;
- X Clone = c;
- X }
- X#endif
- X
- X i++;
- X }
- X (void) closedir(dfp);
- X }
- X/*
- X * Free any directory stack space.
- X */
- X if (dstk != NULL)
- X (void) free((FREE_P *)dstk);
- X/*
- X * Reduce the Devtp[] table to its minimum size.
- X */
- X if (Ndev > i) {
- X Ndev = i;
- X Devtp = (struct dev *)realloc((MALLOC_P *)Devtp,
- X (MALLOC_S)(sizeof(struct dev) * Ndev));
- X }
- X if (err)
- X exit(1);
- X/*
- X * Allocate sorting pointers and sort them by Devtp[] device number.
- X */
- X if ((Sdev = (struct dev **)malloc((MALLOC_S)(sizeof(struct dev *)
- X * Ndev)))
- X == NULL) {
- X (void) fprintf(stderr, "%s: no space for device pointers\n",
- X Pn);
- X exit(1);
- X }
- X for (i = 0; i < Ndev; i++) {
- X Sdev[i] = &Devtp[i];
- X }
- X (void) qsort((QSORT_P *)Sdev,(size_t)Ndev,(size_t)sizeof(struct dev *),
- X compdev);
- X}
- X
- X
- X#if defined(sun)
- X/*
- X * readfifonode() - read fifonode
- X */
- X
- int
- readfifonode(fa, f)
- X caddr_t fa; /* fifonode kernel address */
- X struct fifonode *f; /* fifonode buffer */
- X{
- X if (kread((off_t)fa, (char *)f, sizeof(struct fifonode))) {
- X (void) sprintf(Namech, "can't read fifonode at %#x", fa);
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X#if defined(_IBMR2)
- X/*
- X * readgnode() - read gnode
- X */
- X
- int
- readgnode(ga, g)
- X caddr_t ga; /* gnode kernel address */
- X struct gnode *g; /* gnode buffer */
- X{
- X if (kread((off_t)ga, g, sizeof(struct gnode))) {
- X (void) sprintf(Namech, "can't read gnode at %#x", ga);
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X/*
- X * readinode() - read inode
- X */
- X
- int
- readinode(ia, i)
- X caddr_t ia; /* inode kernel address */
- X struct inode *i; /* inode buffer */
- X{
- X if (kread((off_t)ia, (char *)i, sizeof(struct inode))) {
- X (void) sprintf(Namech, "can't read inode at %#x", ia);
- X return(1);
- X }
- X return(0);
- X}
- X
- X
- X#if defined(DYNIX) || defined(hpux) || defined(NeXT) || defined(sun)
- X/*
- X * readmnt() - read mount table
- X */
- X
- void
- readmnt()
- X{
- X int err = 0;
- X FILE *mfp;
- X struct mntent *mp;
- X struct mounts *mtp;
- X struct stat sb;
- X
- X if ((mfp = setmntent(MOUNTED, "r")) == NULL) {
- X (void) fprintf(stderr, "%s: can't access %s\n", Pn, MOUNTED);
- X exit(1);
- X }
- X while ((mp = getmntent(mfp)) != NULL) {
- X if (statsafely(mp->mnt_dir, &sb, STATTMO))
- X continue;
- X if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
- X == NULL) {
- X err = 1;
- X break;
- X }
- X if ((mtp->dir = (char *)malloc(
- X (MALLOC_S)(strlen(mp->mnt_dir)+1)))
- X == NULL) {
- X err = 1;
- X break;
- X }
- X (void) strcpy(mtp->dir, mp->mnt_dir);
- X if ((mtp->fsname = (char *)malloc(
- X (MALLOC_S)(strlen(mp->mnt_fsname)+1)))
- X == NULL) {
- X err = 1;
- X break;
- X }
- X (void) strcpy(mtp->fsname, mp->mnt_fsname);
- X mtp->next = Mtab;
- X mtp->dev = sb.st_dev;
- X mtp->inode = sb.st_ino;
- X mtp->mode = sb.st_mode;
- X mtp->rdev = sb.st_rdev;
- X Mtab = mtp;
- X }
- X (void) endmntent(mfp);
- X if (err) {
- X (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
- X Pn, mp->mnt_fsname, mp->mnt_dir);
- X exit(1);
- X }
- X}
- X#endif
- X
- X
- X#if defined(_IBMR2)
- X/*
- X * readmnt() - read mount table
- X */
- X
- void
- readmnt()
- X{
- X int err = 0;
- X char *dir, *fs, *h;
- X int fsl;
- X struct mounts *mtp;
- X int nm;
- X struct stat sb;
- X unsigned sz;
- X struct vmount *v, *vt;
- X
- X/*
- X * Read the table of vmount structures.
- X */
- X for (sz = sizeof(struct vmount);;) {
- X if ((vt = (struct vmount *)malloc(sz)) == NULL) {
- X (void) fprintf(stderr,
- X "%s: no space for vmount table\n", Pn);
- X exit(1);
- X }
- X nm = mntctl(MCTL_QUERY, sz, vt);
- X if (nm > 0) {
- X if (vt->vmt_revision != VMT_REVISION) {
- X (void) fprintf(stderr,
- X "%s: stale file system, rev %d != %d\n",
- X Pn, vt->vmt_revision, VMT_REVISION);
- X exit(1);
- X }
- X break;
- X }
- X if (nm == 0) {
- X sz = (unsigned)vt->vmt_revision;
- X (void) free((FREE_P *)vt);
- X } else {
- X (void) fprintf(stderr, "%s: mntctl error: %s\n",
- X Pn, sys_errlist[errno]);
- X exit(1);
- X }
- X }
- X/*
- X * Scan the vmount structures and build Mtab.
- X */
- X for (v = vt; nm--; v = (struct vmount *)((char *)v + v->vmt_length)) {
- X dir = (char *)vmt2dataptr(v, VMT_STUB);
- X fs = (char *)vmt2dataptr(v, VMT_OBJECT);
- X h = (char *)vmt2dataptr(v, VMT_HOST);
- X fsl = strlen(fs);
- X if (v->vmt_flags & MNT_REMOTE)
- X fsl += strlen(h) + 1;
- X if (statsafely(dir, &sb, STATTMO))
- X continue;
- X if ((mtp = (struct mounts *)malloc(sizeof(struct mounts)))
- X == NULL) {
- X err = 1;
- X break;
- X }
- X if ((mtp->dir = (char *)malloc(strlen(dir) + 1)) == NULL) {
- X err = 1;
- X break;
- X }
- X (void) strcpy(mtp->dir, dir);
- X if ((mtp->fsname = (char *)malloc(fsl + 1)) == NULL) {
- X err = 1;
- X break;
- X }
- X if (v->vmt_flags & MNT_REMOTE)
- X (void) sprintf(mtp->fsname, "%s:%s", h, fs);
- X else
- X (void) strcpy(mtp->fsname, fs);
- X mtp->dev = sb.st_dev;
- X mtp->inode = sb.st_ino;
- X mtp->mode = sb.st_mode;
- X mtp->rdev = sb.st_rdev;
- X mtp->next = Mtab;
- X Mtab = mtp;
- X }
- X if (err) {
- X (void) fprintf(stderr, "%s: no space for mount at %s (%s)\n",
- X Pn, fs, dir);
- X exit(1);
- X }
- X (void) free((FREE_P *)vt);
- X}
- X#endif
- X
- X
- X/*
- X * readrnode() - read rnode
- X */
- X
- int
- readrnode(ra, r)
- X caddr_t ra; /* rnode kernel space address */
- X struct rnode *r; /* rnode buffer pointer */
- X{
- X if (kread((off_t)ra, (char *)r, sizeof(struct rnode))) {
- X (void) sprintf(Namech, "can't read rnode at %#x", ra);
- X return(1);
- X }
- X return(0);
- X}
- X
- X
- X#if defined(NeXT) || defined(sun)
- X/*
- X * readsnode() - read snode
- X */
- X
- int
- readsnode(sa, s)
- X caddr_t sa; /* snode kernel space address */
- X struct snode *s; /* snode buffer pointer */
- X{
- X if (kread((off_t)sa, (char *)s, sizeof(struct snode))) {
- X (void) sprintf(Namech, "can't read snode at %#x", sa);
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X#if defined(sun)
- X/*
- X * readtnode() - read tmpnode
- X */
- X
- int
- readtnode(ta, t)
- X caddr_t ta; /* tmpnode kernel space address */
- X struct tmpnode *t; /* tmpnode buffer pointer */
- X{
- X if (kread((off_t)ta, (char *)t, sizeof(struct tmpnode))) {
- X (void) sprintf(Namech, "can't read tmpnode at %#x", ta);
- X return(1);
- X }
- X return(0);
- X}
- X#endif
- X
- X
- X/*
- X * readvfs() - read vfs structure
- X */
- X
- struct l_vfs *
- readvfs(va)
- X struct vfs *va; /* vfs structure kernel address
- X * - e. g., v.v_vfsp */
- X{
- X struct vfs v;
- X struct l_vfs *vp;
- X
- X#if defined(DYNIX) ||defined(hpux) || defined(sun)
- X struct mount m;
- X#endif
- X
- X#if defined(DYNIX) || defined(hpux)
- X struct mntinfo mi;
- X#endif
- X
- X#if defined(_IBMR2)
- X struct gfs g;
- X void *mp;
- X char *s1, *s2;
- X unsigned slen;
- X u_long ul;
- X struct vmount *vm;
- X#endif
- X
- X for (vp = Lvfs; vp; vp = vp->next) {
- X if (va == vp->addr)
- X return(vp);
- X }
- X if ((vp = (struct l_vfs *)malloc(sizeof(struct l_vfs))) == NULL) {
- X (void) fprintf(stderr, "%s: no space for vfs\n", Pn);
- X exit(1);
- X }
- X
- X#if defined(DYNIX) || defined(hpux)
- X vp->dev = 0;
- X#endif
- X
- X vp->dir = NULL;
- X vp->fsname = NULL;
- X
- X#if defined(sun)
- X/*
- X * SunOS vnodes of type VCHR that have a non-null v_stream pointer
- X * represent streams and have no virtual file system pointer.
- X */
- X
- X#endif
- X
- X#if defined(DYNIX) ||defined(hpux) || defined(_IBMR2) || defined(NeXT)
- X if (!va)
- X goto vfs_exit;
- X#endif
- X
- X if (va && kread((off_t)va, (char *)&v, sizeof(v))) {
- X
- X#if defined(DYNIX) || defined(hpux) || defined(_IBMR2) || defined(NeXT)
- X
- vfs_exit:
- X
- X#endif
- X
- X (void) free((FREE_P *)vp);
- X return(NULL);
- X }
- X
- X#if defined(_IBMR2)
- X/*
- X * Locate AIX mount information.
- X */
- X if (kread((off_t) v.vfs_gfs, &g, sizeof(g)))
- X goto vfs_exit;
- X if (kread((off_t) v.vfs_mdata + sizeof(u_long), &ul, sizeof(ul)))
- X goto vfs_exit;
- X if ((mp = malloc((size_t) ul)) == NULL) {
- X (void) fprintf(stderr, "%s: no space for mount data\n", Pn);
- X exit(1);
- X }
- X if (kread((off_t) v.vfs_mdata, mp, (int) ul)) {
- X (void) free((FREE_P *)mp);
- X goto vfs_exit;
- X }
- X vm = (struct vmount *)mp;
- X vp->vmt_flags = vm->vmt_flags;
- X vp->vmt_gfstype = vm->vmt_gfstype;
- X vp->dev = (dev_t)vm->vmt_fsid.fsid_dev;
- X if ((s1 = vmt2dataptr(vm, VMT_STUB)) != NULL) {
- X if ((vp->dir = (char *)malloc(strlen(s1) + 1)) == NULL) {
- X
- readvfs_aix1:
- X (void) fprintf(stderr, "%s: readvfs, no space\n", Pn);
- X exit(1);
- X }
- X (void) strcpy(vp->dir, s1);
- X } else
- X vp->dir = NULL;
- X s1 = vmt2dataptr(vm, VMT_HOST);
- X if ((s2 = vmt2dataptr(vm, VMT_OBJECT)) == NULL || *s1 == '\0')
- X s2 = g.gfs_name;
- X if (s1 == NULL && s2 == NULL)
- X vp->fsname = NULL;
- X else {
- X slen = s2 ? strlen(s2) : 0;
- X if (vm->vmt_flags & MNT_REMOTE)
- X slen += (s1 ? strlen(s1) : 0) + 1;
- X if ((vp->fsname = (char *)malloc(slen + 1)) == NULL)
- X goto readvfs_aix1;
- X if (vm->vmt_flags & MNT_REMOTE)
- X (void) sprintf(vp->fsname, "%s:%s",
- X s1 ? s1 : "", s2 ? s2 : "");
- X else
- X (void) strcpy(vp->fsname, s2 ? s2 : "");
- X }
- X (void) free((FREE_P *)mp);
- X#endif
- X
- X/*
- X * Complete DYNIX, HP-UX and SunOS mount information.
- X */
- X
- X#if defined(DYNIX) || defined(hpux)
- X if (Vtype == V_NFS) {
- X
- X /*
- X * DYNIX and HP-UX NFS vnode device values have a major number of 255.
- X * The minor number is a serial number found in the mntinfo
- X * structure to which the virtual file system's vfs_data points.
- X */
- X if (v.vfs_data
- X && kread((off_t)v.vfs_data, (char *)&mi, sizeof(mi)) == 0)
- X (void) completevfs(vp, makedev(255, mi.mi_mntno));
- X } else {
- X if (kread((off_t)v.vfs_data, (char *)&m, sizeof(m)) == 0)
- X (void) completevfs(vp, m.m_dev);
- X }
- X#endif
- X
- X#if defined(sun)
- X if (va && v.vfs_data && kread((off_t)v.vfs_data, (char *)&m, sizeof(m))
- X == 0)
- X (void) completevfs(vp, m.m_dev);
- X#endif
- X
- X vp->next = Lvfs;
- X vp->addr = va;
- X Lvfs = vp;
- X return(vp);
- X}
- X
- X
- X/*
- X * readvnode() - read vnode
- X */
- X
- int
- readvnode(va, v)
- X caddr_t va; /* vnode kernel space address */
- X struct vnode *v; /* vnode buffer pointer */
- X{
- X if (kread((off_t)va, (char *)v, sizeof(struct vnode))) {
- X (void) sprintf(Namech, "can't read vnode at %#x", va);
- X return(1);
- X }
- X return(0);
- X}
- X
- X
- X/*
- X * statsafely() - stat path safely (i. e., with timeout)
- X */
- X
- statsafely(path, buf, tm)
- X char *path;
- X struct stat *buf;
- X int tm;
- X{
- X int err;
- X static int sverr;
- X
- X if (tm == 0)
- X return(stat(path, buf));
- X sverr = errno;
- X if (setjmp(Tmo_jbuf)) {
- X (void) alarm(0);
- X (void) signal(SIGALRM, SIG_IGN);
- X errno = ETIMEDOUT;
- X return(-1);
- X }
- X (void) signal(SIGALRM, stattimeout);
- X (void) alarm((unsigned)tm);
- X err = stat(path, buf);
- X if (err != 0)
- X sverr = errno;
- X (void) alarm(0);
- X (void) signal(SIGALRM, SIG_IGN);
- X errno = sverr;
- X return(err);
- X}
- X
- X
- X/*
- X * stattimeout() - time out a stat() call
- X */
- X
- X#if defined(DYNIX)
- int
- X#endif
- X
- X#if defined(hpux) || defined(_IBMR2) || defined(NeXT) || defined(sun)
- void
- X#endif
- X
- stattimeout()
- X{
- X (void) alarm(0);
- X (void) signal(SIGALRM, SIG_IGN);
- X longjmp(Tmo_jbuf, 1);
- X}
- X
- X
- X/*
- X * stkdir() - stack directory name
- X */
- X
- void
- stkdir(d, n, x, p)
- X char ***d; /* array of directory pointers */
- X int *n; /* number of pointers */
- X int *x; /* current index */
- X char *p; /* directory path */
- X{
- X if (*d == NULL) {
- X
- X /*
- X * Allocate first entry.
- X */
- X if ((*d = (char **)malloc(sizeof(char *))) == NULL) {
- X
- stkdir_nospace:
- X
- X (void) fprintf(stderr,
- X "%s: no space for directory stack at %s\n",
- X Pn, p);
- X exit(1);
- X }
- X *n = 1;
- X *x = 0;
- X } else if (*x >= *n) {
- X
- X /*
- X * Allocate additional space as required.
- X */
- X *n += 1;
- X if ((*d = (char **)realloc((MALLOC_P *)*d,
- X (MALLOC_S)(*n * sizeof(char *))))
- X == NULL)
- X goto stkdir_nospace;
- X }
- X/*
- X * Allocate space for the name, copy it there and put its pointer on the stack.
- X */
- X if (((*d)[*x] = (char *)malloc((MALLOC_S)(strlen(p) + 1))) == NULL) {
- X (void) fprintf(stderr, "%s: no space for %s\n", Pn, p);
- X exit(1);
- X }
- X (void) strcpy((*d)[*x], p);
- X *x += 1;
- X}
- END_OF_FILE
- if test 79705 -ne `wc -c <'lsof.c'`; then
- echo shar: \"'lsof.c'\" unpacked with wrong size!
- fi
- # end of 'lsof.c'
- fi
- if test ! -d 'sys' ; then
- echo shar: Creating directory \"'sys'\"
- mkdir 'sys'
- fi
- if test -f 'sys/fss.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sys/fss.h'\"
- else
- echo shar: Extracting \"'sys/fss.h'\" \(0 characters\)
- sed "s/^X//" >'sys/fss.h' <<'END_OF_FILE'
- END_OF_FILE
- if test 0 -ne `wc -c <'sys/fss.h'`; then
- echo shar: \"'sys/fss.h'\" unpacked with wrong size!
- fi
- # end of 'sys/fss.h'
- fi
- echo shar: End of shell archive.
- exit 0
-